[KMTESTS/EX]

- Add ExSequencedList test and restructure ExSingleList so they can share the test body

svn path=/branches/GSoC_2011/KMTestSuite/; revision=53359
This commit is contained in:
Thomas Faber
2011-08-21 16:08:27 +00:00
parent a9bba5d113
commit 937c60d74a
6 changed files with 252 additions and 93 deletions
+1
View File
@@ -22,6 +22,7 @@ list(APPEND KMTEST_DRV_SOURCE
ntos_ex/ExInterlocked.c
ntos_ex/ExPools.c
ntos_ex/ExResource.c
ntos_ex/ExSequencedList.c
ntos_ex/ExSingleList.c
ntos_ex/ExTimer.c
ntos_fsrtl/FsRtlExpression.c
+1
View File
@@ -21,6 +21,7 @@
<file>ExInterlocked.c</file>
<file>ExPools.c</file>
<file>ExResource.c</file>
<file>ExSequencedList.c</file>
<file>ExSingleList.c</file>
<file>ExTimer.c</file>
</directory>
+2
View File
@@ -15,6 +15,7 @@ KMT_TESTFUNC Test_ExHardErrorInteractive;
KMT_TESTFUNC Test_ExInterlocked;
KMT_TESTFUNC Test_ExPools;
KMT_TESTFUNC Test_ExResource;
KMT_TESTFUNC Test_ExSequencedList;
KMT_TESTFUNC Test_ExSingleList;
KMT_TESTFUNC Test_ExTimer;
KMT_TESTFUNC Test_FsRtlExpression;
@@ -43,6 +44,7 @@ const KMT_TEST TestList[] =
{ "ExInterlocked", Test_ExInterlocked },
{ "ExPools", Test_ExPools },
{ "ExResource", Test_ExResource },
{ "ExSequencedList", Test_ExSequencedList },
{ "ExSingleList", Test_ExSingleList },
{ "ExTimer", Test_ExTimer },
{ "Example", Test_Example },
+79
View File
@@ -0,0 +1,79 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: GPLv2+ - See COPYING in the top level directory
* PURPOSE: Kernel-Mode Test Suite sequenced singly-linked list test
* PROGRAMMER: Thomas Faber <[email protected]>
*/
struct _SINGLE_LIST_ENTRY;
union _SLIST_HEADER;
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPushEntrySList(union _SLIST_HEADER *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPopEntrySList(union _SLIST_HEADER *, unsigned long *);
#include <kmt_test.h>
/* TODO: SLIST_HEADER is a lot different for x64 */
#define CheckSListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
{ \
ok_eq_pointer((ListHead)->Next.Next, ExpectedPointer); \
/*ok_eq_pointer(FirstEntrySList(ListHead), ExpectedPointer);*/ \
ok_eq_uint((ListHead)->Depth, ExpectedDepth); \
ok_eq_uint((ListHead)->Sequence, ExpectedSequence); \
ok_eq_uint(ExQueryDepthSList(ListHead), ExpectedDepth); \
ok_irql(HIGH_LEVEL); \
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
} while (0)
#define PXLIST_HEADER PSLIST_HEADER
#define PXLIST_ENTRY PSLIST_ENTRY
#define PushXList ExInterlockedPushEntrySList
#define PopXList ExInterlockedPopEntrySList
#define FlushXList ExInterlockedFlushSList
#define ok_free_xlist ok_eq_pointer
#define CheckXListHeader CheckSListHeader
#define TestXListFunctional TestSListFunctional
#include "ExXList.h"
#undef ExInterlockedPushEntrySList
#undef ExInterlockedPopEntrySList
#define TestXListFunctional TestSListFunctionalExports
#include "ExXList.h"
START_TEST(ExSequencedList)
{
PSLIST_HEADER ListHead;
KSPIN_LOCK SpinLock;
USHORT ExpectedSequence = 0;
PKSPIN_LOCK pSpinLock = &SpinLock;
PCHAR Buffer;
PSLIST_ENTRY Entries;
SIZE_T EntriesSize = 5 * sizeof *Entries;
KIRQL Irql;
KeInitializeSpinLock(&SpinLock);
#ifdef _M_IX86
pSpinLock = NULL;
#endif
/* make sure stuff is as un-aligned as possible ;) */
Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLqS');
ListHead = (PVOID)&Buffer[1];
Entries = (PVOID)&ListHead[1];
KeRaiseIrql(HIGH_LEVEL, &Irql);
RtlFillMemory(Entries, EntriesSize, 0x55);
RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
InitializeSListHead(ListHead);
CheckSListHeader(ListHead, NULL, 0);
TestSListFunctional(ListHead, Entries, pSpinLock);
RtlFillMemory(Entries, EntriesSize, 0x55);
RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
ExInitializeSListHead(ListHead);
CheckSListHeader(ListHead, NULL, 0);
TestSListFunctionalExports(ListHead, Entries, pSpinLock);
KeLowerIrql(Irql);
ExFreePoolWithTag(Buffer, 'TLqS');
}
+78 -93
View File
@@ -11,8 +11,6 @@ struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LI
#include <kmt_test.h>
SINGLE_LIST_ENTRY Entries[5];
#define ok_eq_free2(Value, Expected) do \
{ \
if (KmtIsCheckedBuild) \
@@ -21,107 +19,94 @@ SINGLE_LIST_ENTRY Entries[5];
ok_eq_pointer(Value, Expected); \
} while (0)
START_TEST(ExSingleList)
PSINGLE_LIST_ENTRY FlushList(PSINGLE_LIST_ENTRY ListHead)
{
PSINGLE_LIST_ENTRY Ret = ListHead->Next;
ListHead->Next = NULL;
return Ret;
}
USHORT QueryDepthList(PSINGLE_LIST_ENTRY ListHead)
{
USHORT Depth = 0;
while (ListHead->Next)
{
++Depth;
ListHead = ListHead->Next;
}
return Depth;
}
PSINGLE_LIST_ENTRY PushEntryListWrapper(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry, PKSPIN_LOCK Lock)
{
KSPIN_LOCK SpinLock;
SINGLE_LIST_ENTRY ListHead;
PSINGLE_LIST_ENTRY Ret;
UNREFERENCED_PARAMETER(Lock);
Ret = ListHead->Next;
PushEntryList(ListHead, Entry);
return Ret;
}
KeInitializeSpinLock(&SpinLock);
#define CheckListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
{ \
ok_eq_pointer((ListHead)->Next, ExpectedPointer); \
ok_eq_uint(QueryDepthList(ListHead), ExpectedDepth); \
ok_irql(HIGH_LEVEL); \
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
} while (0)
memset(Entries, 0x55, sizeof Entries);
ListHead.Next = NULL;
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(ListHead.Next, NULL);
ok_eq_free2(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, NULL);
ok_eq_free2(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[1], &SpinLock);
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(ListHead.Next, &Entries[1]);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, &Entries[1]);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_free2(Entries[1].Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
#define PXLIST_HEADER PSINGLE_LIST_ENTRY
#define PXLIST_ENTRY PSINGLE_LIST_ENTRY
#define PushXList ExInterlockedPushEntryList
#define PopXList ExInterlockedPopEntryList
#define FlushXList FlushList
#define ok_free_xlist ok_eq_free2
#define CheckXListHeader CheckListHeader
#define TestXListFunctional TestListFunctional
#include "ExXList.h"
#undef ExInterlockedPushEntryList
#undef ExInterlockedPopEntryList
memset(Entries, 0x55, sizeof Entries);
ListHead.Next = NULL;
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
#define TestXListFunctional TestListFunctionalExports
#include "ExXList.h"
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(ListHead.Next, NULL);
ok_eq_free2(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
#undef PushXList
#define PushXList PushEntryListWrapper
#undef PopXList
#define PopXList(h, s) PopEntryList(h)
#undef ok_free_xlist
#define ok_free_xlist ok_eq_pointer
#define TestXListFunctional TestListFunctionalNoInterlocked
#include "ExXList.h"
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, NULL);
ok_eq_free2(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
START_TEST(ExSingleList)
{
KSPIN_LOCK SpinLock;
PSINGLE_LIST_ENTRY ListHead;
PSINGLE_LIST_ENTRY Entries;
SIZE_T EntriesSize = 5 * sizeof *Entries;
PCHAR Buffer;
KIRQL Irql;
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[0], &SpinLock);
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
KeInitializeSpinLock(&SpinLock);
Ret = ExInterlockedPushEntryList(&ListHead, &Entries[1], &SpinLock);
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(ListHead.Next, &Entries[1]);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
/* make sure stuff is as un-aligned as possible ;) */
Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLiS');
ListHead = (PVOID)&Buffer[1];
Entries = (PVOID)&ListHead[1];
KeRaiseIrql(HIGH_LEVEL, &Irql);
RtlFillMemory(Entries, sizeof Entries, 0x55);
ListHead->Next = NULL;
TestListFunctional(ListHead, Entries, &SpinLock);
Ret = ExInterlockedPopEntryList(&ListHead, &SpinLock);
ok_eq_pointer(Ret, &Entries[1]);
ok_eq_pointer(ListHead.Next, &Entries[0]);
ok_eq_free2(Entries[1].Next, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
ok_irql(PASSIVE_LEVEL);
KmtSetIrql(PASSIVE_LEVEL);
RtlFillMemory(Entries, sizeof Entries, 0x55);
ListHead->Next = NULL;
TestListFunctionalExports(ListHead, Entries, &SpinLock);
RtlFillMemory(Entries, sizeof Entries, 0x55);
ListHead->Next = NULL;
TestListFunctionalNoInterlocked(ListHead, Entries, &SpinLock);
KeLowerIrql(Irql);
ExFreePoolWithTag(Buffer, 'TLiS');
}
+91
View File
@@ -0,0 +1,91 @@
/* used by ExSingleList and ExSequencedList tests */
static
VOID
TestXListFunctional(
IN PXLIST_HEADER ListHead,
IN PXLIST_ENTRY Entries,
IN PKSPIN_LOCK pSpinLock)
{
USHORT ExpectedSequence = 0;
PXLIST_ENTRY Ret;
Ret = FlushXList(ListHead);
ok_eq_pointer(Ret, NULL);
CheckXListHeader(ListHead, NULL, 0);
Ret = PopXList(ListHead, pSpinLock);
ok_eq_pointer(Ret, NULL);
CheckXListHeader(ListHead, NULL, 0);
Ret = PushXList(ListHead, &Entries[0], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(Entries[0].Next, NULL);
CheckXListHeader(ListHead, &Entries[0], 1);
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, &Entries[1], 2);
Ret = PopXList(ListHead, pSpinLock);
ok_eq_pointer(Ret, &Entries[1]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_free_xlist(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, &Entries[0], 1);
Ret = PopXList(ListHead, pSpinLock);
ok_eq_pointer(Ret, &Entries[0]);
ok_free_xlist(Entries[0].Next, NULL);
ok_free_xlist(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, NULL, 0);
Ret = PopXList(ListHead, pSpinLock);
ok_eq_pointer(Ret, NULL);
ok_free_xlist(Entries[0].Next, NULL);
ok_free_xlist(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, NULL, 0);
/* add entries again */
Ret = PushXList(ListHead, &Entries[0], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, NULL);
ok_eq_pointer(Entries[0].Next, NULL);
CheckXListHeader(ListHead, &Entries[0], 1);
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, &Entries[1], 2);
Ret = PopXList(ListHead, pSpinLock);
ok_eq_pointer(Ret, &Entries[1]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_free_xlist(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, &Entries[0], 1);
Ret = PushXList(ListHead, &Entries[1], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, &Entries[0]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
CheckXListHeader(ListHead, &Entries[1], 2);
Ret = PushXList(ListHead, &Entries[2], pSpinLock);
++ExpectedSequence;
ok_eq_pointer(Ret, &Entries[1]);
ok_eq_pointer(Entries[0].Next, NULL);
ok_eq_pointer(Entries[1].Next, &Entries[0]);
ok_eq_pointer(Entries[2].Next, &Entries[1]);
CheckXListHeader(ListHead, &Entries[2], 3);
Ret = FlushXList(ListHead);
ok_eq_pointer(Ret, &Entries[2]);
CheckXListHeader(ListHead, NULL, 0);
}
#undef TestXListFunctional