9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/* $Id$ */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** @file
b736c553dbde2c3b2533c93c57d9b7f07714371cvboxsync * IPRT - Testcase Framework.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2013 Oracle Corporation
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * available from http://www.virtualbox.org. This file is free software;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * General Public License (GPL) as published by the Free Software
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * The contents of this file may alternatively be used under the terms
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * of the Common Development and Distribution License Version 1.0
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * VirtualBox OSE distribution, in which case the provisions of the
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * CDDL are applicable instead of those of the GPL.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * You may elect to license modified versions of this file under the
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * terms and conditions of either the GPL or the CDDL or both.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*******************************************************************************
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync* Header Files *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync*******************************************************************************/
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include <iprt/test.h>
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync#include <iprt/asm.h>
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync#include <iprt/critsect.h>
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync#include <iprt/env.h>
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync#include <iprt/err.h>
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync#include <iprt/file.h>
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync#include <iprt/initterm.h>
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include <iprt/mem.h>
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync#include <iprt/once.h>
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include <iprt/param.h>
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync#include <iprt/pipe.h>
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include <iprt/string.h>
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include <iprt/stream.h>
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#include "internal/magics.h"
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*******************************************************************************
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync* Structures and Typedefs *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync*******************************************************************************/
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Guarded memory allocation record.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsynctypedef struct RTTESTGUARDEDMEM
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** Pointer to the next record. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync struct RTTESTGUARDEDMEM *pNext;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The address we return to the user. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync void *pvUser;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The base address of the allocation. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync void *pvAlloc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The size of the allocation. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync size_t cbAlloc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** Guards. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync struct
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The guard address. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync void *pv;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The guard size. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync size_t cb;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync } aGuards[2];
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync} RTTESTGUARDEDMEM;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Pointer to an guarded memory allocation. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsynctypedef RTTESTGUARDEDMEM *PRTTESTGUARDEDMEM;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Test instance structure.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsynctypedef struct RTTESTINT
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** Magic. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync uint32_t u32Magic;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The number of errors. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync volatile uint32_t cErrors;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The test name. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync const char *pszTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The length of the test name. */
9474d83dcac691984017f8255821b95ec7642804vboxsync size_t cchTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The size of a guard. Multiple of PAGE_SIZE. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync uint32_t cbGuard;
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The verbosity level. */
9474d83dcac691984017f8255821b95ec7642804vboxsync RTTESTLVL enmMaxLevel;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync /** The creation flags. */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync uint32_t fFlags;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** Critical section serializing output. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCRITSECT OutputLock;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** The output stream. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTSTREAM pOutStrm;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /** Whether we're currently at a newline. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync bool fNewLine;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** Critical section serializing access to the members following it. */
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCRITSECT Lock;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The list of guarded memory allocations. */
9474d83dcac691984017f8255821b95ec7642804vboxsync PRTTESTGUARDEDMEM pGuardedMem;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The current sub-test. */
9474d83dcac691984017f8255821b95ec7642804vboxsync const char *pszSubTest;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** The length of the sub-test name. */
9474d83dcac691984017f8255821b95ec7642804vboxsync size_t cchSubTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync /** Whether the current subtest should figure as 'SKIPPED'. */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync bool fSubTestSkipped;
9474d83dcac691984017f8255821b95ec7642804vboxsync /** Whether we've reported the sub-test result or not. */
9474d83dcac691984017f8255821b95ec7642804vboxsync bool fSubTestReported;
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The start error count of the current subtest. */
9474d83dcac691984017f8255821b95ec7642804vboxsync uint32_t cSubTestAtErrors;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The number of sub tests. */
9474d83dcac691984017f8255821b95ec7642804vboxsync uint32_t cSubTests;
9474d83dcac691984017f8255821b95ec7642804vboxsync /** The number of sub tests that failed. */
9474d83dcac691984017f8255821b95ec7642804vboxsync uint32_t cSubTestsFailed;
9474d83dcac691984017f8255821b95ec7642804vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** Set if XML output is enabled. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync bool fXmlEnabled;
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync /** Set if we omit the top level test in the XML report. */
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync bool fXmlOmitTopTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync /** Set if we've reported the top test (for RTTEST_C_XML_DELAY_TOP_TEST). */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync bool fXmlTopTestDone;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync enum {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync kXmlPos_ValueStart,
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync kXmlPos_Value,
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync kXmlPos_ElementEnd
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync } eXmlState;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** Test pipe for the XML output stream going to the server. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTPIPE hXmlPipe;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** File where the XML output stream might be directed. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTFILE hXmlFile;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** The number of XML elements on the stack. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync size_t cXmlElements;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /** XML element stack. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync const char *apszXmlElements[10];
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync} RTTESTINT;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Pointer to a test instance. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsynctypedef RTTESTINT *PRTTESTINT;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*******************************************************************************
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync* Defined Constants And Macros *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync*******************************************************************************/
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Validate a test instance. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#define RTTEST_VALID_RETURN(pTest) \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync do { \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertPtrReturn(pTest, VERR_INVALID_HANDLE); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertReturn(pTest->u32Magic == RTTESTINT_MAGIC, VERR_INVALID_HANDLE); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync } while (0)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Gets and validates a test instance.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * If the handle is nil, we will try retrieve it from the test TLS entry.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#define RTTEST_GET_VALID_RETURN(pTest) \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync do { \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pTest == NIL_RTTEST) \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest = (PRTTESTINT)RTTlsGet(g_iTestTls); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertPtrReturn(pTest, VERR_INVALID_HANDLE); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertReturn(pTest->u32Magic == RTTESTINT_MAGIC, VERR_INVALID_MAGIC); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync } while (0)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Gets and validates a test instance.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * If the handle is nil, we will try retrieve it from the test TLS entry.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync#define RTTEST_GET_VALID_RETURN_RC(pTest, rc) \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync do { \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pTest == NIL_RTTEST) \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest = (PRTTESTINT)RTTlsGet(g_iTestTls); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertPtrReturn(pTest, (rc)); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertReturn(pTest->u32Magic == RTTESTINT_MAGIC, (rc)); \
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync } while (0)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*******************************************************************************
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync* Internal Functions *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync*******************************************************************************/
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic void rtTestGuardedFreeOne(PRTTESTGUARDEDMEM pMem);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic int rtTestPrintf(PRTTESTINT pTest, const char *pszFormat, ...);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlStart(PRTTESTINT pTest, const char *pszTest);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElem(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemStartV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemStart(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemEnd(PRTTESTINT pTest, const char *pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlEnd(PRTTESTINT pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/*******************************************************************************
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync* Global Variables *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync*******************************************************************************/
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** For serializing TLS init. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic RTONCE g_TestInitOnce = RTONCE_INITIALIZER;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/** Our TLS entry. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic RTTLS g_iTestTls = NIL_RTTLS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Init TLS index once.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser Ignored.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncstatic DECLCALLBACK(int32_t) rtTestInitOnce(void *pvUser)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
a438caaf732f7839dc66b4f8dad672527845a003vboxsync NOREF(pvUser);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return RTTlsAllocEx(&g_iTestTls, NULL);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(int) RTTestCreateEx(const char *pszTest, uint32_t fFlags, RTTESTLVL enmMaxLevel,
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTHCINTPTR iNativeTestPipe, const char *pszXmlFile, PRTTEST phTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertReturn(!(fFlags & ~RTTEST_C_VALID_MASK), VERR_INVALID_PARAMETER);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertPtrNull(phTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertPtrNull(pszXmlFile);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync /* RTTESTLVL_INVALID is valid! */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertReturn(enmMaxLevel >= RTTESTLVL_INVALID && enmMaxLevel < RTTESTLVL_END, VERR_INVALID_PARAMETER);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Global init.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
a438caaf732f7839dc66b4f8dad672527845a003vboxsync int rc = RTOnce(&g_TestInitOnce, rtTestInitOnce, NULL);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_FAILURE(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return rc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Create the instance.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = (PRTTESTINT)RTMemAllocZ(sizeof(*pTest));
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (!pTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VERR_NO_MEMORY;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->u32Magic = RTTESTINT_MAGIC;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pszTest = RTStrDup(pszTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cchTest = strlen(pszTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cbGuard = PAGE_SIZE * 7;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = enmMaxLevel == RTTESTLVL_INVALID ? RTTESTLVL_INFO : enmMaxLevel;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fFlags = fFlags;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pOutStrm = g_pStdOut;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->fNewLine = true;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pGuardedMem = NULL;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pszSubTest = NULL;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cchSubTest = 0;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fSubTestSkipped = false;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->fSubTestReported = true;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTestAtErrors = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTests = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTestsFailed = 0;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->fXmlEnabled = false;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fXmlTopTestDone = false;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->hXmlPipe = NIL_RTPIPE;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->hXmlFile = NIL_RTFILE;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements = 0;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTCritSectInit(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTCritSectInit(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Associate it with our TLS entry unless there is already
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * an instance there.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
a2c64fa551ce727fe368a0ce60d5583e8fbd1c62vboxsync if ( !(fFlags & RTTEST_C_NO_TLS)
a2c64fa551ce727fe368a0ce60d5583e8fbd1c62vboxsync && !RTTlsGet(g_iTestTls))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTTlsSet(g_iTestTls, pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync /*
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync * Output level override?
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync char szEnvVal[RTPATH_MAX];
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if ((fFlags & RTTEST_C_USE_ENV) && enmMaxLevel == RTTESTLVL_INVALID)
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_MAX_LEVEL", szEnvVal, sizeof(szEnvVal), NULL);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_SUCCESS(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync char *pszMaxLevel = RTStrStrip(szEnvVal);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!strcmp(pszMaxLevel, "all"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_DEBUG;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!strcmp(pszMaxLevel, "quiet"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_FAILURE;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (!strcmp(pszMaxLevel, "debug"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_DEBUG;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (!strcmp(pszMaxLevel, "info"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_INFO;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (!strcmp(pszMaxLevel, "sub_test"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_SUB_TEST;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (!strcmp(pszMaxLevel, "failure"))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->enmMaxLevel = RTTESTLVL_FAILURE;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (rc != VERR_ENV_VAR_NOT_FOUND)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTEnvGetEx(IPRT_TEST_MAX_LEVEL) -> %Rrc\n", pszTest, rc);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync }
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /*
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Any test driver we are connected or should connect to?
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if ((fFlags & RTTEST_C_USE_ENV) && iNativeTestPipe == -1)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_PIPE", szEnvVal, sizeof(szEnvVal), NULL);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_SUCCESS(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync#if ARCH_BITS == 64
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTStrToInt64Full(szEnvVal, 0, &iNativeTestPipe);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync#else
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTStrToInt32Full(szEnvVal, 0, &iNativeTestPipe);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync#endif
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_FAILURE(rc))
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTStrToInt32Full(\"%s\") -> %Rrc\n",
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pszTest, szEnvVal, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync iNativeTestPipe = -1;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (rc != VERR_ENV_VAR_NOT_FOUND)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTEnvGetEx(IPRT_TEST_PIPE) -> %Rrc\n", pszTest, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (iNativeTestPipe != -1)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTPipeFromNative(&pTest->hXmlPipe, iNativeTestPipe, RTPIPE_N_WRITE);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_SUCCESS(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fXmlEnabled = true;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTPipeFromNative(,%p,WRITE) -> %Rrc\n",
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pszTest, iNativeTestPipe, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->hXmlPipe = NIL_RTPIPE;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /*
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Any test file we should write the test report to?
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if ((fFlags & RTTEST_C_USE_ENV) && pszXmlFile == NULL)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTEnvGetEx(RTENV_DEFAULT, "IPRT_TEST_FILE", szEnvVal, sizeof(szEnvVal), NULL);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_SUCCESS(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pszXmlFile = szEnvVal;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else if (rc != VERR_ENV_VAR_NOT_FOUND)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test pipe error: RTEnvGetEx(IPRT_TEST_MAX_LEVEL) -> %Rrc\n", pszTest, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (pszXmlFile && *pszXmlFile)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTFileOpen(&pTest->hXmlFile, pszXmlFile,
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_TRUNCATE);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (RT_SUCCESS(rc))
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->fXmlEnabled = true;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: test file error: RTFileOpen(,\"%s\",) -> %Rrc\n", pszTest, pszXmlFile, rc);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->hXmlFile = NIL_RTFILE;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else if (rc != VERR_ENV_VAR_NOT_FOUND)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTStrmPrintf(g_pStdErr, "%s: test file error: RTEnvGetEx(IPRT_TEST_FILE) -> %Rrc\n", pszTest, rc);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /*
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync * What do we report in the XML stream/file.?
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync */
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fXmlOmitTopTest = (fFlags & RTTEST_C_XML_OMIT_TOP_TEST)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync || ( (fFlags & RTTEST_C_USE_ENV)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync && RTEnvExistEx(RTENV_DEFAULT, "IPRT_TEST_OMIT_TOP_TEST"));
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync /*
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync * Tell the test driver that we're up to.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlStart(pTest, pszTest);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *phTest = pTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /* bail out. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectDelete(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectDelete(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->u32Magic = 0;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrFree((char *)pTest->pszTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTMemFree(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return rc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(int) RTTestCreate(const char *pszTest, PRTTEST phTest)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return RTTestCreateEx(pszTest, RTTEST_C_USE_ENV, RTTESTLVL_INVALID, -1 /*iNativeTestPipe*/, NULL /*pszXmlFile*/, phTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsyncRTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest)
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync{
230bd8589bba39933ac5ec21482d6186d675e604vboxsync int rc = RTR3InitExeNoArguments(0);
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync if (RT_FAILURE(rc))
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync {
230bd8589bba39933ac5ec21482d6186d675e604vboxsync RTStrmPrintf(g_pStdErr, "%s: fatal error: RTR3InitExeNoArguments failed with rc=%Rrc\n", pszTest, rc);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return RTEXITCODE_INIT;
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTTestCreate(pszTest, phTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_FAILURE(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: fatal error: RTTestCreate failed with rc=%Rrc\n", pszTest, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return RTEXITCODE_INIT;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return RTEXITCODE_SUCCESS;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(RTEXITCODE) RTTestInitExAndCreate(int cArgs, char ***papszArgs, uint32_t fRtInit, const char *pszTest, PRTTEST phTest)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync int rc;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (cArgs <= 0 && papszArgs == NULL)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTR3InitExeNoArguments(fRtInit);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rc = RTR3InitExe(cArgs, papszArgs, fRtInit);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (RT_FAILURE(rc))
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrmPrintf(g_pStdErr, "%s: fatal error: RTR3InitExe(,,%#x) failed with rc=%Rrc\n", pszTest, fRtInit, rc);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return RTEXITCODE_INIT;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync rc = RTTestCreate(pszTest, phTest);
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync if (RT_FAILURE(rc))
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTStrmPrintf(g_pStdErr, "%s: fatal error: RTTestCreate failed with rc=%Rrc\n", pszTest, rc);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return RTEXITCODE_INIT;
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync }
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return RTEXITCODE_SUCCESS;
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync}
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync
174e1d5b2d6b6d7c92271d7fcc070c6d0cc92312vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Destroys a test instance previously created by RTTestCreate.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. NIL_RTTEST is ignored.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestDestroy(RTTEST hTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Validate
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (hTest == NIL_RTTEST)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTESTINT *pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_VALID_RETURN(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync /*
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Make sure we end with a new line and have finished up the XML.
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync */
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync if (!pTest->fNewLine)
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync rtTestPrintf(pTest, "\n");
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlEnd(pTest);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Clean up.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if ((RTTESTINT *)RTTlsGet(g_iTestTls) == pTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTlsSet(g_iTestTls, NULL);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync ASMAtomicWriteU32(&pTest->u32Magic, ~RTTESTINT_MAGIC);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectDelete(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectDelete(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /* free guarded memory. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTGUARDEDMEM pMem = pTest->pGuardedMem;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->pGuardedMem = NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync while (pMem)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTGUARDEDMEM pFree = pMem;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem = pMem->pNext;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rtTestGuardedFreeOne(pFree);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTStrFree((char *)pTest->pszSubTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pszSubTest = NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrFree((char *)pTest->pszTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->pszTest = NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTMemFree(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync/**
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync * Changes the default test instance for the calling thread.
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync *
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync * @returns IPRT status code.
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync *
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync * @param hNewDefaultTest The new default test. NIL_RTTEST is fine.
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync * @param phOldTest Where to store the old test handle. Optional.
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync */
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsyncRTR3DECL(int) RTTestSetDefault(RTTEST hNewDefaultTest, PRTTEST phOldTest)
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync{
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync if (phOldTest)
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync *phOldTest = (RTTEST)RTTlsGet(g_iTestTls);
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync return RTTlsSet(g_iTestTls, hNewDefaultTest);
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync}
da769a9c0c94bad4a9c3bd895ea53837b58dc4d4vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(int) RTTestChangeName(RTTEST hTest, const char *pszName)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync PRTTESTINT pTest = hTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN(pTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertPtrReturn(pszName, VERR_INVALID_POINTER);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertReturn(*pszName, VERR_INVALID_PARAMETER);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync size_t cchName = strlen(pszName);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertReturn(cchName < 128, VERR_INVALID_PARAMETER);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync char *pszDupName = RTStrDup(pszName);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!pszDupName)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return VERR_NO_STR_MEMORY;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectEnter(&pTest->Lock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectEnter(&pTest->OutputLock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync char *pszOldName = (char *)pTest->pszTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->pszTest = pszDupName;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->cchTest = cchName;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectLeave(&pTest->OutputLock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectLeave(&pTest->Lock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTStrFree(pszOldName);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return VINF_SUCCESS;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Allocate a block of guarded memory.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param cb The amount of memory to allocate.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param cbAlign The alignment of the returned block.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param fHead Head or tail optimized guard.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param ppvUser Where to return the pointer to the block.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestGuardedAlloc(RTTEST hTest, size_t cb, uint32_t cbAlign, bool fHead, void **ppvUser)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_GET_VALID_RETURN(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (cbAlign == 0)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync cbAlign = 1;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertReturn(cbAlign <= PAGE_SIZE, VERR_INVALID_PARAMETER);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync AssertReturn(cbAlign == (UINT32_C(1) << (ASMBitFirstSetU32(cbAlign) - 1)), VERR_INVALID_PARAMETER);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Allocate the record and block and initialize them.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int rc = VERR_NO_MEMORY;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTGUARDEDMEM pMem = (PRTTESTGUARDEDMEM)RTMemAlloc(sizeof(*pMem));
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_LIKELY(pMem))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
74407ed9ebae51fb7a33c31f2965f7e105a626ebvboxsync size_t const cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->aGuards[0].cb = pMem->aGuards[1].cb = pTest->cbGuard;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->cbAlloc = pMem->aGuards[0].cb + pMem->aGuards[1].cb + cbAligned;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->pvAlloc = RTMemPageAlloc(pMem->cbAlloc);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pMem->pvAlloc)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->aGuards[0].pv = pMem->pvAlloc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->pvUser = (uint8_t *)pMem->pvAlloc + pMem->aGuards[0].cb;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->aGuards[1].pv = (uint8_t *)pMem->pvUser + cbAligned;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (!fHead)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync size_t off = cb & PAGE_OFFSET_MASK;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (off)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync off = PAGE_SIZE - RT_ALIGN_Z(off, cbAlign);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->pvUser = (uint8_t *)pMem->pvUser + off;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Set up the guards and link the record.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync ASMMemFill32(pMem->aGuards[0].pv, pMem->aGuards[0].cb, 0xdeadbeef);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync ASMMemFill32(pMem->aGuards[1].pv, pMem->aGuards[1].cb, 0xdeadbeef);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTMemProtect(pMem->aGuards[0].pv, pMem->aGuards[0].cb, RTMEM_PROT_NONE);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTMemProtect(pMem->aGuards[1].pv, pMem->aGuards[1].cb, RTMEM_PROT_NONE);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *ppvUser = pMem->pvUser;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectEnter(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pMem->pNext = pTest->pGuardedMem;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->pGuardedMem = pMem;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectLeave(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTMemProtect(pMem->aGuards[0].pv, pMem->aGuards[0].cb, RTMEM_PROT_WRITE | RTMEM_PROT_READ);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
c307f0d7384bfc4d19d2290a28be89868f02f42avboxsync RTMemPageFree(pMem->pvAlloc, pMem->cbAlloc);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTMemFree(pMem);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return rc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Allocates a block of guarded memory where the guarded is immediately after
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * the user memory.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Pointer to the allocated memory. NULL on failure.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param cb The amount of memory to allocate.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(void *) RTTestGuardedAllocTail(RTTEST hTest, size_t cb)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync void *pvUser;
cab76ca44de9dee4db92033691f646d5b1323df2vboxsync int rc = RTTestGuardedAlloc(hTest, cb, 1 /* cbAlign */, false /* fHead */, &pvUser);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return pvUser;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Allocates a block of guarded memory where the guarded is right in front of
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * the user memory.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Pointer to the allocated memory. NULL on failure.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param cb The amount of memory to allocate.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(void *) RTTestGuardedAllocHead(RTTEST hTest, size_t cb)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync void *pvUser;
cab76ca44de9dee4db92033691f646d5b1323df2vboxsync int rc = RTTestGuardedAlloc(hTest, cb, 1 /* cbAlign */, true /* fHead */, &pvUser);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (RT_SUCCESS(rc))
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return pvUser;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Frees one block of guarded memory.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * The caller is responsible for unlinking it.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pMem The memory record.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic void rtTestGuardedFreeOne(PRTTESTGUARDEDMEM pMem)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int rc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTMemProtect(pMem->aGuards[0].pv, pMem->aGuards[0].cb, RTMEM_PROT_WRITE | RTMEM_PROT_READ); AssertRC(rc);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = RTMemProtect(pMem->aGuards[1].pv, pMem->aGuards[1].cb, RTMEM_PROT_WRITE | RTMEM_PROT_READ); AssertRC(rc);
c307f0d7384bfc4d19d2290a28be89868f02f42avboxsync RTMemPageFree(pMem->pvAlloc, pMem->cbAlloc);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTMemFree(pMem);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Frees a block of guarded memory.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pv The memory. NULL is ignored.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestGuardedFree(RTTEST hTest, void *pv)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_GET_VALID_RETURN(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (!pv)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /*
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Find it.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int rc = VERR_INVALID_POINTER;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTGUARDEDMEM pPrev = NULL;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectEnter(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync for (PRTTESTGUARDEDMEM pMem = pTest->pGuardedMem; pMem; pMem = pMem->pNext)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pMem->pvUser == pv)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pPrev)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pPrev->pNext = pMem->pNext;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync else
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->pGuardedMem = pMem->pNext;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rtTestGuardedFreeOne(pMem);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync rc = VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync break;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pPrev = pMem;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectLeave(&pTest->Lock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
0b07f19b2d822b86714ed48e3581477a046f1c79vboxsync return rc;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Outputs the formatted XML.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszFormat The format string.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param va The format arguments.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlOutputV(PRTTESTINT pTest, const char *pszFormat, va_list va)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync char *pszStr;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync ssize_t cchStr = RTStrAPrintfV(&pszStr, pszFormat, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pszStr)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->hXmlPipe != NIL_RTPIPE)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTPipeWriteBlocking(pTest->hXmlPipe, pszStr, cchStr, NULL);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->hXmlFile != NIL_RTFILE)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTFileWrite(pTest->hXmlFile, pszStr, cchStr, NULL);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTStrFree(pszStr);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Outputs the formatted XML.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszFormat The format string.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param ... The format arguments.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlOutput(PRTTESTINT pTest, const char *pszFormat, ...)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_start(va, pszFormat);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutputV(pTest, pszFormat, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Starts the XML stream.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszTest The test name.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlStart(PRTTESTINT pTest, const char *pszTest)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements = 0;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
9c2453b230526193ea4d5cf5a735dbff69a85a36vboxsync pTest->fXmlTopTestDone = !(pTest->fFlags & RTTEST_C_XML_DELAY_TOP_TEST) || pTest->fXmlOmitTopTest;
9c2453b230526193ea4d5cf5a735dbff69a85a36vboxsync if (pTest->fXmlTopTestDone && !pTest->fXmlOmitTopTest)
9c2453b230526193ea4d5cf5a735dbff69a85a36vboxsync rtTestXmlElemStart(pTest, "Test", "name=%RMas", pszTest);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Emit an XML element that doesn't have any value and instead ends immediately.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * The caller must own the instance lock.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszTag The element tag.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszAttrFmt The element attributes as a format string. Use
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * NULL if none.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param va Format string arguments.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTIMESPEC TimeSpec;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTIME Time;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync char szTS[80];
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTimeToString(RTTimeExplode(&Time, RTTimeNow(&TimeSpec)), szTS, sizeof(szTS));
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->eXmlState != RTTESTINT::kXmlPos_ElementEnd)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "\n");
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (!pszAttrFmt || !*pszAttrFmt)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas/>\n",
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements * 2, "", pszTag, szTS);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va2;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_copy(va2, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas %N/>\n",
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements * 2, "", pszTag, szTS, pszAttrFmt, &va2);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va2);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Wrapper around rtTestXmlElemV.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElem(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_start(va, pszAttrFmt);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlElemV(pTest, pszTag, pszAttrFmt, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Starts a new XML element.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * The caller must own the instance lock.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszTag The element tag.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszAttrFmt The element attributes as a format string. Use
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * NULL if none.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param va Format string arguments.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemStartV(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, va_list va)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /* Push it onto the stack. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync size_t i = pTest->cXmlElements;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync AssertReturnVoid(i < RT_ELEMENTS(pTest->apszXmlElements));
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->apszXmlElements[i] = pszTag;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements = i + 1;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTIMESPEC TimeSpec;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTIME Time;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync char szTS[80];
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTimeToString(RTTimeExplode(&Time, RTTimeNow(&TimeSpec)), szTS, sizeof(szTS));
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->eXmlState != RTTESTINT::kXmlPos_ElementEnd)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "\n");
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (!pszAttrFmt || !*pszAttrFmt)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas>",
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync i * 2, "", pszTag, szTS);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va2;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_copy(va2, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s<%s timestamp=%RMas %N>",
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync i * 2, "", pszTag, szTS, pszAttrFmt, &va2);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va2);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ValueStart;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Wrapper around rtTestXmlElemStartV.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemStart(PRTTESTINT pTest, const char *pszTag, const char *pszAttrFmt, ...)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_start(va, pszAttrFmt);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlElemStartV(pTest, pszTag, pszAttrFmt, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Ends the current element.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * The caller must own the instance lock.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pszTag The tag we're ending (chiefly for sanity
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * checking).
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlElemEnd(PRTTESTINT pTest, const char *pszTag)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /* pop the element */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync size_t i = pTest->cXmlElements;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync AssertReturnVoid(i > 0);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync i--;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync AssertReturnVoid(!strcmp(pszTag, pTest->apszXmlElements[i]));
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements = i;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /* Do the closing. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->eXmlState == RTTESTINT::kXmlPos_ValueStart)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "\n%*s</%s>\n", i * 2, "", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else if (pTest->eXmlState == RTTESTINT::kXmlPos_ElementEnd)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s</%s>\n", i * 2, "", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "</%s>\n", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Ends the XML stream, closing all open elements.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * The caller must own the instance lock.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param pTest The test instance.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic void rtTestXmlEnd(PRTTESTINT pTest)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->fXmlEnabled)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /*
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Close all the elements and add the final TestEnd one to get a
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * final timestamp and some certainty that the XML is valid.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync size_t i = pTest->cXmlElements;
9c2453b230526193ea4d5cf5a735dbff69a85a36vboxsync AssertReturnVoid(i > 0 || pTest->fXmlOmitTopTest || !pTest->fXmlTopTestDone);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync while (i-- > 1)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync const char *pszTag = pTest->apszXmlElements[pTest->cXmlElements];
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->eXmlState == RTTESTINT::kXmlPos_ValueStart)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "\n%*s</%s>\n", i * 2, "", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else if (pTest->eXmlState == RTTESTINT::kXmlPos_ElementEnd)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "%*s</%s>\n", i * 2, "", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync else
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlOutput(pTest, "</%s>\n", pszTag);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!pTest->fXmlOmitTopTest && pTest->fXmlTopTestDone)
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync {
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync rtTestXmlElem(pTest, "End", "SubTests=\"%u\" SubTestsFailed=\"%u\" errors=\"%u\"",
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync pTest->cSubTests, pTest->cSubTestsFailed, pTest->cErrors);
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync rtTestXmlOutput(pTest, "</Test>\n");
666e2c9af6a34f7a05d8069a11194756312f5be6vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /*
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Close the XML outputs.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->hXmlPipe != NIL_RTPIPE)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTPipeClose(pTest->hXmlPipe);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->hXmlPipe = NIL_RTPIPE;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (pTest->hXmlFile != NIL_RTFILE)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTFileClose(pTest->hXmlFile);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->hXmlFile = NIL_RTFILE;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->fXmlEnabled = false;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->eXmlState = RTTESTINT::kXmlPos_ElementEnd;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync pTest->cXmlElements = 0;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Output callback.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns number of bytes written.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pvArg User argument.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pachChars Pointer to an array of utf-8 characters.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param cbChars Number of bytes in the character array pointed to by pachChars.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic DECLCALLBACK(size_t) rtTestPrintfOutput(void *pvArg, const char *pachChars, size_t cbChars)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync size_t cch = 0;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = (PRTTESTINT)pvArg;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (cbChars)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync do
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /* insert prefix if at a newline. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (pTest->fNewLine)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrmWrite(pTest->pOutStrm, pTest->pszTest, pTest->cchTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrmWrite(pTest->pOutStrm, ": ", 2);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync cch += 2 + pTest->cchTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync /* look for newline and write the stuff. */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync const char *pchEnd = (const char *)memchr(pachChars, '\n', cbChars);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (!pchEnd)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->fNewLine = false;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrmWrite(pTest->pOutStrm, pachChars, cbChars);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync cch += cbChars;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync break;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pTest->fNewLine = true;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync size_t const cchPart = pchEnd - pachChars + 1;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrmWrite(pTest->pOutStrm, pachChars, cchPart);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync cch += cchPart;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync pachChars += cchPart;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync cbChars -= cchPart;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync } while (cbChars);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync else
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTStrmFlush(pTest->pOutStrm);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Internal output worker.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Caller takes the lock.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pTest The test instance.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param va The arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic int rtTestPrintfV(PRTTESTINT pTest, const char *pszFormat, va_list va)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
74407ed9ebae51fb7a33c31f2965f7e105a626ebvboxsync return (int)RTStrFormatV(rtTestPrintfOutput, pTest, NULL, NULL, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Internal output worker.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Caller takes the lock.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pTest The test instance.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param ... The arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncstatic int rtTestPrintf(PRTTESTINT pTest, const char *pszFormat, ...)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_list va;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_start(va, pszFormat);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int cch = rtTestPrintfV(pTest, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_end(va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Test vprintf making sure the output starts on a new line.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param enmLevel Message importance level.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param va Arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestPrintfNlV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, -1);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectEnter(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (enmLevel <= pTest->enmMaxLevel)
9474d83dcac691984017f8255821b95ec7642804vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync if (!pTest->fNewLine)
9474d83dcac691984017f8255821b95ec7642804vboxsync cch += rtTestPrintf(pTest, "\n");
9474d83dcac691984017f8255821b95ec7642804vboxsync cch += rtTestPrintfV(pTest, pszFormat, va);
9474d83dcac691984017f8255821b95ec7642804vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectLeave(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Test printf making sure the output starts on a new line.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param enmLevel Message importance level.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param ... Arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestPrintfNl(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_list va;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_start(va, pszFormat);
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = RTTestPrintfNlV(hTest, enmLevel, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_end(va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Test vprintf, makes sure lines are prefixed and so forth.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param enmLevel Message importance level.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param va Arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestPrintfV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, -1);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectEnter(&pTest->OutputLock);
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (enmLevel <= pTest->enmMaxLevel)
9474d83dcac691984017f8255821b95ec7642804vboxsync cch += rtTestPrintfV(pTest, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTCritSectLeave(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Test printf, makes sure lines are prefixed and so forth.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param enmLevel Message importance level.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param ... Arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestPrintf(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_list va;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_start(va, pszFormat);
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = RTTestPrintfV(hTest, enmLevel, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_end(va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Prints the test banner.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Number of chars printed.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestBanner(RTTEST hTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync return RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "TESTING...\n");
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
9474d83dcac691984017f8255821b95ec7642804vboxsync * Prints the result of a sub-test if necessary.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
9474d83dcac691984017f8255821b95ec7642804vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param pTest The test instance.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @remarks Caller own the test Lock.
9474d83dcac691984017f8255821b95ec7642804vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncstatic int rtTestSubTestReport(PRTTESTINT pTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if ( !pTest->fSubTestReported
9474d83dcac691984017f8255821b95ec7642804vboxsync && pTest->pszSubTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->fSubTestReported = true;
9474d83dcac691984017f8255821b95ec7642804vboxsync uint32_t cErrors = ASMAtomicUoReadU32(&pTest->cErrors) - pTest->cSubTestAtErrors;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (!cErrors)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!pTest->fSubTestSkipped)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rtTestXmlElem(pTest, "Passed", NULL);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rtTestXmlElemEnd(pTest, "Test");
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-50s: PASSED\n", pTest->pszSubTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync else
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rtTestXmlElem(pTest, "Skipped", NULL);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rtTestXmlElemEnd(pTest, "Test");
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-50s: SKIPPED\n", pTest->pszSubTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
9474d83dcac691984017f8255821b95ec7642804vboxsync else
9474d83dcac691984017f8255821b95ec7642804vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTestsFailed++;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync rtTestXmlElem(pTest, "Failed", "errors=\"%u\"", cErrors);
a29b9359f5b5df63ed9b0f84f5e88e70b481ef3avboxsync rtTestXmlElemEnd(pTest, "Test");
ca0cc01613315de53a5be2ae820cf918635bb861vboxsync cch += RTTestPrintfNl(pTest, RTTESTLVL_SUB_TEST, "%-50s: FAILED (%u errors)\n",
ca0cc01613315de53a5be2ae820cf918635bb861vboxsync pTest->pszSubTest, cErrors);
9474d83dcac691984017f8255821b95ec7642804vboxsync }
9474d83dcac691984017f8255821b95ec7642804vboxsync }
9474d83dcac691984017f8255821b95ec7642804vboxsync return cch;
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
9474d83dcac691984017f8255821b95ec7642804vboxsync * RTTestSub and RTTestSubDone worker that cleans up the current (if any)
9474d83dcac691984017f8255821b95ec7642804vboxsync * sub test.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
9474d83dcac691984017f8255821b95ec7642804vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param pTest The test instance.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @remarks Caller own the test Lock.
9474d83dcac691984017f8255821b95ec7642804vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncstatic int rtTestSubCleanup(PRTTESTINT pTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (pTest->pszSubTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync cch += rtTestSubTestReport(pTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTStrFree((char *)pTest->pszSubTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pszSubTest = NULL;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->fSubTestReported = true;
9474d83dcac691984017f8255821b95ec7642804vboxsync }
9474d83dcac691984017f8255821b95ec7642804vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Summaries the test, destroys the test instance and return an exit code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns Test program exit code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsyncRTR3DECL(RTEXITCODE) RTTestSummaryAndDestroy(RTTEST hTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, RTEXITCODE_FAILURE);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectEnter(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync rtTestSubTestReport(pTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectLeave(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync RTEXITCODE enmExitCode;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync if (!pTest->cErrors)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "SUCCESS\n", pTest->cErrors);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync enmExitCode = RTEXITCODE_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync else
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "FAILURE - %u errors\n", pTest->cErrors);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync enmExitCode = RTEXITCODE_FAILURE;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync RTTestDestroy(pTest);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return enmExitCode;
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync}
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsyncRTR3DECL(RTEXITCODE) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va)
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync{
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync PRTTESTINT pTest = hTest;
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, RTEXITCODE_SKIPPED);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync RTCritSectEnter(&pTest->Lock);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync rtTestSubTestReport(pTest);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync RTCritSectLeave(&pTest->Lock);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync RTEXITCODE enmExitCode;
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync if (!pTest->cErrors)
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync {
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync if (pszReasonFmt)
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync RTTestPrintfNlV(hTest, RTTESTLVL_FAILURE, pszReasonFmt, va);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "SKIPPED\n", pTest->cErrors);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync enmExitCode = RTEXITCODE_SKIPPED;
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync }
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync else
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync {
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "FAILURE - %u errors\n", pTest->cErrors);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync enmExitCode = RTEXITCODE_FAILURE;
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync }
9474d83dcac691984017f8255821b95ec7642804vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTestDestroy(pTest);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return enmExitCode;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsyncRTR3DECL(RTEXITCODE) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...)
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync{
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync va_list va;
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync va_start(va, pszReasonFmt);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync RTEXITCODE enmExitCode = RTTestSkipAndDestroyV(hTest, pszReasonFmt, va);
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync va_end(va);
9c77b083e2ca3a9b509faa9789072f2527422e22vboxsync return enmExitCode;
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync}
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
50ba3040a0c2b77a195a8239e3572d0036e4b86dvboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
9474d83dcac691984017f8255821b95ec7642804vboxsync * Starts a sub-test.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
9474d83dcac691984017f8255821b95ec7642804vboxsync * This will perform an implicit RTTestSubDone() call if that has not been done
9474d83dcac691984017f8255821b95ec7642804vboxsync * since the last RTTestSub call.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
9474d83dcac691984017f8255821b95ec7642804vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9474d83dcac691984017f8255821b95ec7642804vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param pszSubTest The sub-test name
9474d83dcac691984017f8255821b95ec7642804vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestSub(RTTEST hTest, const char *pszSubTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync PRTTESTINT pTest = hTest;
9474d83dcac691984017f8255821b95ec7642804vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, -1);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectEnter(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync /* Cleanup, reporting if necessary previous sub test. */
9474d83dcac691984017f8255821b95ec7642804vboxsync rtTestSubCleanup(pTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync /* Start new sub test. */
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTests++;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cSubTestAtErrors = ASMAtomicUoReadU32(&pTest->cErrors);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->pszSubTest = RTStrDup(pszSubTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->cchSubTest = strlen(pszSubTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fSubTestSkipped = false;
9474d83dcac691984017f8255821b95ec7642804vboxsync pTest->fSubTestReported = false;
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (pTest->enmMaxLevel >= RTTESTLVL_DEBUG)
9474d83dcac691984017f8255821b95ec7642804vboxsync cch = RTTestPrintfNl(hTest, RTTESTLVL_DEBUG, "debug: Starting sub-test '%s'\n", pszSubTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (!pTest->fXmlTopTestDone)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fXmlTopTestDone = true;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync rtTestXmlElemStart(pTest, "Test", "name=%RMas", pTest->pszTest);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
a29b9359f5b5df63ed9b0f84f5e88e70b481ef3avboxsync rtTestXmlElemStart(pTest, "Test", "name=%RMas", pszSubTest);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectLeave(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync return cch;
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync/**
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * Format string version of RTTestSub.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync *
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * See RTTestSub for details.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync *
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @returns Number of chars printed.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * associated with the calling thread.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param pszSubTestFmt The sub-test name format string.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param ... Arguments.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync */
d544fe535c163a24bf8cd831b39264da292b8adfvboxsyncRTR3DECL(int) RTTestSubF(RTTEST hTest, const char *pszSubTestFmt, ...)
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync{
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync va_list va;
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync va_start(va, pszSubTestFmt);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync int cch = RTTestSubV(hTest, pszSubTestFmt, va);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync va_end(va);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync return cch;
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync}
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync/**
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * Format string version of RTTestSub.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync *
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * See RTTestSub for details.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync *
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @returns Number of chars printed.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * associated with the calling thread.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param pszSubTestFmt The sub-test name format string.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync * @param ... Arguments.
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync */
d544fe535c163a24bf8cd831b39264da292b8adfvboxsyncRTR3DECL(int) RTTestSubV(RTTEST hTest, const char *pszSubTestFmt, va_list va)
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync{
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync char *pszSubTest;
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync RTStrAPrintfV(&pszSubTest, pszSubTestFmt, va);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync if (pszSubTest)
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync {
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync int cch = RTTestSub(hTest, pszSubTest);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync RTStrFree(pszSubTest);
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync return cch;
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync }
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync return 0;
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync}
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
d544fe535c163a24bf8cd831b39264da292b8adfvboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
9474d83dcac691984017f8255821b95ec7642804vboxsync * Completes a sub-test.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
9474d83dcac691984017f8255821b95ec7642804vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9474d83dcac691984017f8255821b95ec7642804vboxsync * associated with the calling thread.
9474d83dcac691984017f8255821b95ec7642804vboxsync */
9474d83dcac691984017f8255821b95ec7642804vboxsyncRTR3DECL(int) RTTestSubDone(RTTEST hTest)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync PRTTESTINT pTest = hTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectEnter(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = rtTestSubCleanup(pTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectLeave(&pTest->Lock);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync return cch;
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync/**
904ef975124106054684a976dfb30f70372372e1vboxsync * Prints an extended PASSED message, optional.
904ef975124106054684a976dfb30f70372372e1vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * This does not conclude the sub-test, it could be used to report the passing
904ef975124106054684a976dfb30f70372372e1vboxsync * of a sub-sub-to-the-power-of-N-test.
904ef975124106054684a976dfb30f70372372e1vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * @returns IPRT status code.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
904ef975124106054684a976dfb30f70372372e1vboxsync * associated with the calling thread.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param pszFormat The message. No trailing newline.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param va The arguments.
904ef975124106054684a976dfb30f70372372e1vboxsync */
904ef975124106054684a976dfb30f70372372e1vboxsyncRTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va)
904ef975124106054684a976dfb30f70372372e1vboxsync{
904ef975124106054684a976dfb30f70372372e1vboxsync PRTTESTINT pTest = hTest;
9a78c6f7d35bf9ad6072e27ee1ecbb00aaf232c5vboxsync AssertPtr(pszFormat);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync int cch = 0;
904ef975124106054684a976dfb30f70372372e1vboxsync if (pTest->enmMaxLevel >= RTTESTLVL_INFO)
904ef975124106054684a976dfb30f70372372e1vboxsync {
904ef975124106054684a976dfb30f70372372e1vboxsync va_list va2;
904ef975124106054684a976dfb30f70372372e1vboxsync va_copy(va2, va);
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync RTCritSectEnter(&pTest->OutputLock);
904ef975124106054684a976dfb30f70372372e1vboxsync cch += rtTestPrintf(pTest, "%N\n", pszFormat, &va2);
904ef975124106054684a976dfb30f70372372e1vboxsync RTCritSectLeave(&pTest->OutputLock);
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync va_end(va2);
904ef975124106054684a976dfb30f70372372e1vboxsync }
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync return cch;
904ef975124106054684a976dfb30f70372372e1vboxsync}
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync/**
904ef975124106054684a976dfb30f70372372e1vboxsync * Prints an extended PASSED message, optional.
904ef975124106054684a976dfb30f70372372e1vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * This does not conclude the sub-test, it could be used to report the passing
904ef975124106054684a976dfb30f70372372e1vboxsync * of a sub-sub-to-the-power-of-N-test.
904ef975124106054684a976dfb30f70372372e1vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * @returns IPRT status code.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
904ef975124106054684a976dfb30f70372372e1vboxsync * associated with the calling thread.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param pszFormat The message. No trailing newline.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param ... The arguments.
904ef975124106054684a976dfb30f70372372e1vboxsync */
904ef975124106054684a976dfb30f70372372e1vboxsyncRTR3DECL(int) RTTestPassed(RTTEST hTest, const char *pszFormat, ...)
904ef975124106054684a976dfb30f70372372e1vboxsync{
904ef975124106054684a976dfb30f70372372e1vboxsync va_list va;
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync va_start(va, pszFormat);
904ef975124106054684a976dfb30f70372372e1vboxsync int cch = RTTestPassedV(hTest, pszFormat, va);
904ef975124106054684a976dfb30f70372372e1vboxsync va_end(va);
904ef975124106054684a976dfb30f70372372e1vboxsync
904ef975124106054684a976dfb30f70372372e1vboxsync return cch;
904ef975124106054684a976dfb30f70372372e1vboxsync}
904ef975124106054684a976dfb30f70372372e1vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(int) RTTestSkippedV(RTTEST hTest, const char *pszFormat, va_list va)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync PRTTESTINT pTest = hTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync AssertPtrNull(pszFormat);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync pTest->fSubTestSkipped = true;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync int cch = 0;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync if (pszFormat && *pszFormat && pTest->enmMaxLevel >= RTTESTLVL_INFO)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync {
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_list va2;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_copy(va2, va);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectEnter(&pTest->OutputLock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync cch += rtTestPrintf(pTest, "%N\n", pszFormat, &va2);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTCritSectLeave(&pTest->OutputLock);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_end(va2);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync }
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return cch;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(int) RTTestSkipped(RTTEST hTest, const char *pszFormat, ...)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_list va;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_start(va, pszFormat);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync int cch = RTTestSkippedV(hTest, pszFormat, va);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync va_end(va);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return cch;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync/**
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * Gets the unit name.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync *
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @returns Unit name.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync * @param enmUnit The unit.
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncstatic const char *rtTestUnitName(RTTESTUNIT enmUnit)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync switch (enmUnit)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync {
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_PCT: return "%";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_BYTES: return "bytes";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_BYTES_PER_SEC: return "bytes/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_KILOBYTES: return "KB";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_KILOBYTES_PER_SEC: return "KB/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_MEGABYTES: return "MB";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_MEGABYTES_PER_SEC: return "MB/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_PACKETS: return "packets";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_PACKETS_PER_SEC: return "packets/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_FRAMES: return "frames";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_FRAMES_PER_SEC: return "frames/";
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync case RTTESTUNIT_OCCURRENCES: return "occurrences";
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync case RTTESTUNIT_OCCURRENCES_PER_SEC: return "occurrences/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_ROUND_TRIP: return "roundtrips";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_CALLS: return "calls";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_CALLS_PER_SEC: return "calls/s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_SECS: return "s";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_MS: return "ms";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_NS: return "ns";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_NS_PER_CALL: return "ns/call";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_NS_PER_FRAME: return "ns/frame";
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync case RTTESTUNIT_NS_PER_OCCURRENCE: return "ns/occurrences";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_NS_PER_PACKET: return "ns/packet";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_NS_PER_ROUND_TRIP: return "ns/roundtrips";
e8f169c27c5303b27b62741c66ed248e14771f9dvboxsync case RTTESTUNIT_INSTRS: return "ins";
e8f169c27c5303b27b62741c66ed248e14771f9dvboxsync case RTTESTUNIT_INSTRS_PER_SEC: return "ins/sec";
e8f169c27c5303b27b62741c66ed248e14771f9dvboxsync case RTTESTUNIT_NONE: return "";
69891f8dd7430725700b34d2c6b0222c69c69c53vboxsync case RTTESTUNIT_PP1K: return "pp1k";
69891f8dd7430725700b34d2c6b0222c69c69c53vboxsync case RTTESTUNIT_PP10K: return "pp10k";
69891f8dd7430725700b34d2c6b0222c69c69c53vboxsync case RTTESTUNIT_PPM: return "ppm";
69891f8dd7430725700b34d2c6b0222c69c69c53vboxsync case RTTESTUNIT_PPB: return "ppb";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync /* No default so gcc helps us keep this up to date. */
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_INVALID:
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync case RTTESTUNIT_END:
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync break;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync }
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync AssertMsgFailed(("%d\n", enmUnit));
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync return "unknown";
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncRTR3DECL(int) RTTestValue(RTTEST hTest, const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync PRTTESTINT pTest = hTest;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTTEST_GET_VALID_RETURN(pTest);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync const char *pszUnit = rtTestUnitName(enmUnit);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTCritSectEnter(&pTest->Lock);
a29b9359f5b5df63ed9b0f84f5e88e70b481ef3avboxsync rtTestXmlElem(pTest, "Value", "name=%RMas unit=%RMas value=\"%llu\"", pszName, pszUnit, u64Value);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTCritSectLeave(&pTest->Lock);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTCritSectEnter(&pTest->OutputLock);
de76629d72613c3a1c05814ee44ad9108a7f007evboxsync rtTestPrintf(pTest, " %-48s: %'16llu %s\n", pszName, u64Value, pszUnit);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTCritSectLeave(&pTest->OutputLock);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync return VINF_SUCCESS;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncRTR3DECL(int) RTTestValueF(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_list va;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_start(va, pszNameFmt);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync int rc = RTTestValueV(hTest, u64Value, enmUnit, pszNameFmt, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync va_end(va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync return rc;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsyncRTR3DECL(int) RTTestValueV(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync{
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync char *pszName;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTStrAPrintfV(&pszName, pszNameFmt, va);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync if (!pszName)
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync return VERR_NO_MEMORY;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync int rc = RTTestValue(hTest, pszName, u64Value, enmUnit);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync RTStrFree(pszName);
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync return rc;
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync}
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
97566036db1dc1dba46ed21be4e147c728fd1027vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Increments the error counter.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestErrorInc(RTTEST hTest)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync RTTEST_GET_VALID_RETURN(pTest);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync ASMAtomicIncU32(&pTest->cErrors);
9474d83dcac691984017f8255821b95ec7642804vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return VINF_SUCCESS;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync/**
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync * Get the current error count.
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync *
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync * @returns The error counter, UINT32_MAX if no valid test handle.
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync * associated with the calling thread.
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync */
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsyncRTR3DECL(uint32_t) RTTestErrorCount(RTTEST hTest)
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync{
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync PRTTESTINT pTest = hTest;
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync RTTEST_GET_VALID_RETURN_RC(pTest, UINT32_MAX);
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync return ASMAtomicReadU32(&pTest->cErrors);
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync}
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync
4fb518cb2eadd86a2bf117501cd38b05dde47745vboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsyncRTR3DECL(uint32_t) RTTestSubErrorCount(RTTEST hTest)
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync{
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync PRTTESTINT pTest = hTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN_RC(pTest, UINT32_MAX);
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync return ASMAtomicReadU32(&pTest->cErrors) - pTest->cSubTestAtErrors;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync}
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Increments the error counter and prints a failure message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message. No trailing newline.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param va The arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestFailedV(RTTEST hTest, const char *pszFormat, va_list va)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync PRTTESTINT pTest = hTest;
b379286f0d2c8d82f5a575eb907c7476aa6ae84bvboxsync RTTEST_GET_VALID_RETURN_RC(pTest, VERR_INVALID_HANDLE);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTTestErrorInc(pTest);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync int cch = 0;
9474d83dcac691984017f8255821b95ec7642804vboxsync if (pTest->enmMaxLevel >= RTTESTLVL_FAILURE)
9474d83dcac691984017f8255821b95ec7642804vboxsync {
9474d83dcac691984017f8255821b95ec7642804vboxsync va_list va2;
9474d83dcac691984017f8255821b95ec7642804vboxsync va_copy(va2, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
f869309f635f9316b613a848e218b7661e3a54bdvboxsync const char *pszEnd = strchr(pszFormat, '\0');
f869309f635f9316b613a848e218b7661e3a54bdvboxsync bool fHasNewLine = pszFormat != pszEnd
f869309f635f9316b613a848e218b7661e3a54bdvboxsync && pszEnd[-1] == '\n';
f869309f635f9316b613a848e218b7661e3a54bdvboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectEnter(&pTest->OutputLock);
f869309f635f9316b613a848e218b7661e3a54bdvboxsync cch += rtTestPrintf(pTest, fHasNewLine ? "%N" : "%N\n", pszFormat, &va2);
9474d83dcac691984017f8255821b95ec7642804vboxsync RTCritSectLeave(&pTest->OutputLock);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync va_end(va2);
9474d83dcac691984017f8255821b95ec7642804vboxsync }
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync/**
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * Increments the error counter and prints a failure message.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync *
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @returns IPRT status code.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * associated with the calling thread.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param pszFormat The message. No trailing newline.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync * @param ... The arguments.
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync */
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsyncRTR3DECL(int) RTTestFailed(RTTEST hTest, const char *pszFormat, ...)
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync{
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_list va;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_start(va, pszFormat);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync int cch = RTTestFailedV(hTest, pszFormat, va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync va_end(va);
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync return cch;
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync}
9cabb72c6d6feb65e839ce50765643b98bb9a301vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
904ef975124106054684a976dfb30f70372372e1vboxsync * Same as RTTestPrintfV with RTTESTLVL_FAILURE.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9474d83dcac691984017f8255821b95ec7642804vboxsync * associated with the calling thread.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param pszFormat The message.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param va Arguments.
9474d83dcac691984017f8255821b95ec7642804vboxsync */
904ef975124106054684a976dfb30f70372372e1vboxsyncRTR3DECL(int) RTTestFailureDetailsV(RTTEST hTest, const char *pszFormat, va_list va)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
904ef975124106054684a976dfb30f70372372e1vboxsync return RTTestPrintfV(hTest, RTTESTLVL_FAILURE, pszFormat, va);
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync
9474d83dcac691984017f8255821b95ec7642804vboxsync/**
904ef975124106054684a976dfb30f70372372e1vboxsync * Same as RTTestPrintf with RTTESTLVL_FAILURE.
9474d83dcac691984017f8255821b95ec7642804vboxsync *
904ef975124106054684a976dfb30f70372372e1vboxsync * @returns Number of chars printed.
9474d83dcac691984017f8255821b95ec7642804vboxsync * @param hTest The test handle. If NIL_RTTEST we'll use the one
9474d83dcac691984017f8255821b95ec7642804vboxsync * associated with the calling thread.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param pszFormat The message.
904ef975124106054684a976dfb30f70372372e1vboxsync * @param ... Arguments.
9474d83dcac691984017f8255821b95ec7642804vboxsync */
904ef975124106054684a976dfb30f70372372e1vboxsyncRTR3DECL(int) RTTestFailureDetails(RTTEST hTest, const char *pszFormat, ...)
9474d83dcac691984017f8255821b95ec7642804vboxsync{
9474d83dcac691984017f8255821b95ec7642804vboxsync va_list va;
9474d83dcac691984017f8255821b95ec7642804vboxsync va_start(va, pszFormat);
904ef975124106054684a976dfb30f70372372e1vboxsync int cch = RTTestFailureDetailsV(hTest, pszFormat, va);
9474d83dcac691984017f8255821b95ec7642804vboxsync va_end(va);
9474d83dcac691984017f8255821b95ec7642804vboxsync return cch;
9474d83dcac691984017f8255821b95ec7642804vboxsync}
9474d83dcac691984017f8255821b95ec7642804vboxsync