From ba63f36790f3d5ddd096a05728fd952dec33dd45 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 19 Jun 2011 09:23:03 +0000 Subject: [PATCH] [KMTESTS] - add the proper testing framework functions for winetest-like feel - remove thereby obsolete Log* functions - update example test to show usage of the new macros svn path=/branches/GSoC_2011/KMTestSuite/; revision=52359 --- kmtests/CMakeLists.txt | 1 - kmtests/example/Example.c | 11 ++- kmtests/include/kmt_log.h | 21 ------ kmtests/include/kmt_test.h | 119 +++++++++++++++++++++++++++++++- kmtests/kmtest/kmtest.c | 2 + kmtests/kmtest_drv.rbuild | 26 ++++++- kmtests/kmtest_drv/kmtest_drv.c | 9 +-- kmtests/kmtest_drv/log.c | 102 --------------------------- 8 files changed, 154 insertions(+), 137 deletions(-) delete mode 100644 kmtests/include/kmt_log.h delete mode 100644 kmtests/kmtest_drv/log.c diff --git a/kmtests/CMakeLists.txt b/kmtests/CMakeLists.txt index faa38ae6dae..877b742cb24 100644 --- a/kmtests/CMakeLists.txt +++ b/kmtests/CMakeLists.txt @@ -11,7 +11,6 @@ include_directories( # list(APPEND KMTEST_DRV_SOURCE kmtest_drv/kmtest_drv.c - kmtest_drv/log.c kmtest_drv/testlist.c example/Example.c diff --git a/kmtests/example/Example.c b/kmtests/example/Example.c index 2ee5633d132..ee0c56b897d 100644 --- a/kmtests/example/Example.c +++ b/kmtests/example/Example.c @@ -7,10 +7,15 @@ #include #include -#include VOID Test_Example(VOID) { - /* TODO: this should be trace(), as in winetests */ - LogPrint("Message from kernel\n"); + KIRQL Irql; + + ok(1, "This test should succeed.\n"); + ok(0, "This test should fail.\n"); + trace("Message from kernel, low-irql. %s. %ls.\n", "Format strings work", L"Even with Unicode"); + KeRaiseIrql(HIGH_LEVEL, &Irql); + trace("Message from kernel, high-irql. %s. %ls.\n", "Format strings work", L"Even with Unicode"); + KeLowerIrql(Irql); } diff --git a/kmtests/include/kmt_log.h b/kmtests/include/kmt_log.h deleted file mode 100644 index 53f2b536277..00000000000 --- a/kmtests/include/kmt_log.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * PROJECT: ReactOS kernel-mode tests - * LICENSE: GPLv2+ - See COPYING in the top level directory - * PURPOSE: Kernel-Mode Test Suite Driver logging function declarations - * PROGRAMMER: Thomas Faber - */ - -#ifndef _KMTEST_LOG_H_ -#define _KMTEST_LOG_H_ - -#include - -NTSTATUS LogInit(VOID); -VOID LogFree(VOID); - -VOID LogPrint(IN PCSTR Message); -VOID LogPrintF(IN PCSTR Format, ...); -VOID LogVPrintF(IN PCSTR Format, va_list Arguments); -SIZE_T LogRead(OUT PVOID Buffer, IN SIZE_T BufferSize); - -#endif /* !defined _KMTEST_LOG_H_ */ diff --git a/kmtests/include/kmt_test.h b/kmtests/include/kmt_test.h index 032893b20df..447d77551fa 100644 --- a/kmtests/include/kmt_test.h +++ b/kmtests/include/kmt_test.h @@ -1,10 +1,15 @@ /* * PROJECT: ReactOS kernel-mode tests * LICENSE: GPLv2+ - See COPYING in the top level directory - * PURPOSE: Kernel-Mode Test Suite test declarations + * PURPOSE: Kernel-Mode Test Suite test framework declarations * PROGRAMMER: Thomas Faber */ +/* Inspired by Wine C unit tests, Copyright (C) 2002 Alexandre Julliard + * Inspired by ReactOS kernel-mode regression tests, + * Copyright (C) Aleksey Bragin, Filip Navara + */ + #ifndef _KMTEST_TEST_H_ #define _KMTEST_TEST_H_ @@ -32,6 +37,18 @@ typedef struct { extern PKMT_RESULTBUFFER ResultBuffer; +#define KMT_STRINGIZE(x) #x +#define ok(test, ...) ok_(test, __FILE__, __LINE__, __VA_ARGS__) +#define trace(...) trace_( __FILE__, __LINE__, __VA_ARGS__) + +#define ok_(test, file, line, ...) KmtOk(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__) +#define trace_(file, line, ...) KmtTrace( file ":" KMT_STRINGIZE(line), __VA_ARGS__) + +VOID KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments); +VOID KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...); +VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments); +VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...); + #if defined KMT_DEFINE_TEST_FUNCTIONS PKMT_RESULTBUFFER ResultBuffer = NULL; @@ -55,6 +72,8 @@ static VOID KmtFreeResultBuffer(PKMT_RESULTBUFFER Buffer) #endif /* defined KMT_USER_MODE */ #define KmtMemCpy memcpy +#define KmtStrLen strlen +#define KmtAssert assert static VOID KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer, PCSTR String, SIZE_T Length) { @@ -82,6 +101,104 @@ INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_l #define KmtVSNPrintF vsnprintf #endif /* defined KMT_USER_MODE */ +static SIZE_T KmtXVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Prepend1, PCSTR Prepend2, PCSTR Format, va_list Arguments) +{ + SIZE_T BufferLength = 0; + SIZE_T Length; + + if (Prepend1) + { + SIZE_T Length = min(BufferMaxLength, KmtStrLen(Prepend1)); + KmtMemCpy(Buffer, Prepend1, Length); + Buffer += Length; + BufferLength += Length; + BufferMaxLength -= Length; + } + if (Prepend2) + { + SIZE_T Length = min(BufferMaxLength, KmtStrLen(Prepend2)); + KmtMemCpy(Buffer, Prepend2, Length); + Buffer += Length; + BufferLength += Length; + BufferMaxLength -= Length; + } + Length = KmtVSNPrintF(Buffer, BufferMaxLength, Format, Arguments); + /* vsnprintf can return more than maxLength, we don't want to do that */ + BufferLength += min(Length, BufferMaxLength); + return BufferLength; +} + +static SIZE_T KmtXSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Prepend1, PCSTR Prepend2, PCSTR Format, ...) +{ + SIZE_T BufferLength; + va_list Arguments; + va_start(Arguments, Format); + BufferLength = KmtXVSNPrintF(Buffer, BufferMaxLength, Prepend1, Prepend2, Format, Arguments); + va_end(Arguments); + return BufferLength; +} + +VOID KmtFinishTest(PCSTR TestName) +{ + CHAR MessageBuffer[512]; + SIZE_T MessageLength; + + MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, NULL, NULL, + "%s: %d tests executed (0 marked as todo, %d failures), 0 skipped.\n", + TestName, + ResultBuffer->Successes + ResultBuffer->Failures, + ResultBuffer->Failures); + KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); +} + +VOID KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) +{ + CHAR MessageBuffer[512]; + SIZE_T MessageLength; + + if (Condition) + { + InterlockedIncrement(&ResultBuffer->Successes); + + if (0/*KmtReportSuccess*/) + { + MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test succeeded\n", ""); + KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); + } + } + else + { + InterlockedIncrement(&ResultBuffer->Failures); + MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test failed: ", Format, Arguments); + KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); + } +} + +VOID KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) +{ + va_list Arguments; + va_start(Arguments, Format); + KmtVOk(Condition, FileAndLine, Format, Arguments); + va_end(Arguments); +} + +VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments) +{ + CHAR MessageBuffer[512]; + SIZE_T MessageLength; + + MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": ", Format, Arguments); + KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); +} + +VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) +{ + va_list Arguments; + va_start(Arguments, Format); + KmtVTrace(FileAndLine, Format, Arguments); + va_end(Arguments); +} + #endif /* defined KMT_DEFINE_TEST_FUNCTIONS */ #endif /* !defined _KMTEST_TEST_H_ */ diff --git a/kmtests/kmtest/kmtest.c b/kmtests/kmtest/kmtest.c index 619acc869b1..f8c29024d27 100644 --- a/kmtests/kmtest/kmtest.c +++ b/kmtests/kmtest/kmtest.c @@ -74,6 +74,8 @@ static DWORD RunTest(char *testName) goto cleanup; } + KmtFinishTest(testName); + if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), ResultBuffer->LogBuffer, ResultBuffer->LogBufferLength, &bytesWritten, NULL)) { error = GetLastError(); diff --git a/kmtests/kmtest_drv.rbuild b/kmtests/kmtest_drv.rbuild index 5d43511da18..effd37fe2a5 100644 --- a/kmtests/kmtest_drv.rbuild +++ b/kmtests/kmtest_drv.rbuild @@ -4,13 +4,37 @@ ntdll hal pseh + kmtest_printf kmtest_drv.c - log.c testlist.c Example.c + + include + + + KmtWcToMb + + printf_stubs.c + + + + + + + + + streamout.c + + + + + + + + diff --git a/kmtests/kmtest_drv/kmtest_drv.c b/kmtests/kmtest_drv/kmtest_drv.c index 39c4194c153..b2ed98c5735 100644 --- a/kmtests/kmtest_drv/kmtest_drv.c +++ b/kmtests/kmtest_drv/kmtest_drv.c @@ -14,7 +14,7 @@ #include #include -#include +#define KMT_DEFINE_TEST_FUNCTIONS #include /* Prototypes */ @@ -59,11 +59,6 @@ NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING Re DPRINT("DriverEntry\n"); - Status = LogInit(); - - if (!NT_SUCCESS(Status)) - goto cleanup; - RtlInitUnicodeString(&DeviceName, L"\\Device\\Kmtest"); Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, @@ -119,8 +114,6 @@ static VOID NTAPI DriverUnload(IN PDRIVER_OBJECT DriverObject) ASSERT(!ResultBuffer); IoDeleteDevice(MainDeviceObject); } - - LogFree(); } /** diff --git a/kmtests/kmtest_drv/log.c b/kmtests/kmtest_drv/log.c deleted file mode 100644 index 9dda0939364..00000000000 --- a/kmtests/kmtest_drv/log.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * PROJECT: ReactOS kernel-mode tests - * LICENSE: GPLv2+ - See COPYING in the top level directory - * PURPOSE: Kernel-Mode Test Suite Driver logging functions - * PROGRAMMER: Thomas Faber - */ - -#include -#include - -#include -#define KMT_DEFINE_TEST_FUNCTIONS -#include - -/** - * @name LogInit - * - * Initialize logging mechanism. Call from DriverEntry. - * - * @return Status - */ -NTSTATUS LogInit(VOID) -{ - NTSTATUS Status = STATUS_SUCCESS; - PAGED_CODE(); - - return Status; -} - -/** - * @name LogFree - * - * Clean up logging mechanism. Call from Unload. - * - * @return None - */ -VOID LogFree(VOID) -{ - PAGED_CODE(); -} - -/** - * @name LogPrint - * - * Print a log message. - * - * @param Message - * Ansi string to be logged - * - * @return None - */ -VOID LogPrint(IN PCSTR Message) -{ - size_t MessageLength; - ASSERT(NT_SUCCESS(RtlStringCbLengthA(Message, 512, &MessageLength))); - - KmtAddToLogBuffer(ResultBuffer, Message, MessageLength); -} - -/** - * @name LogPrintF - * - * Print a formatted log message. - * - * @param Format - * printf-like format string - * @param ... - * Arguments corresponding to the format - * - * @return None - */ -VOID LogPrintF(IN PCSTR Format, ...) -{ - va_list Arguments; - PAGED_CODE(); - va_start(Arguments, Format); - LogVPrintF(Format, Arguments); - va_end(Arguments); -} - -/** - * @name LogVPrintF - * - * Print a formatted log message. - * - * @param Format - * printf-like format string - * @param Arguments - * Arguments corresponding to the format - * - * @return None - */ -VOID LogVPrintF(IN PCSTR Format, va_list Arguments) -{ - CHAR Buffer[512]; - /* TODO: make this work from any IRQL */ - PAGED_CODE(); - - RtlStringCbVPrintfA(Buffer, sizeof Buffer, Format, Arguments); - - LogPrint(Buffer); -}