Skip to content

Commit

Permalink
Fix nasa#550, add function groups to ut assert
Browse files Browse the repository at this point in the history
Clean up and Refactor the internal list storage structures to support
having multiple list heads/groups.  Define a separate list/group for
setup, normal test, and teardown.

The existing UtTest_Add() routine maps to the normal test group.
Added a UtTest_AddSetup() and UtTest_AddTeardown() routine that maps
to the setup and teardown group, respectively.

The existing UtTest_Run() routine then merges the groups and executes
the full suite of tests.

This allows separate, dynamic registration of test setup and teardown
routines which are executed before and after the normal test routine,
which can create and delete any global/common test prerequisites.
  • Loading branch information
jphickey committed Jul 31, 2020
1 parent 8cfd6fe commit 9a9171c
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 136 deletions.
52 changes: 18 additions & 34 deletions ut_assert/inc/utlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ typedef struct UtListNodeTag {
} UtListNode_t;

typedef struct {
UtListNode_t *First;
UtListNode_t *Last;
uint32 NumberOfEntries;
UtListNode_t *Tags;
uint32 NumberOfTags;
} UtListHead_t;

/*
Expand All @@ -75,54 +74,39 @@ typedef struct UtListNodeTag {
/* Dynamically allocates a new list head. A list head could also just be declared, this function is useful
* if you need to dynamically allocate memory for a new list head. Note always free list heads allocated by
* this function by calling UtList_Destroy. */
UtListHead_t *UtList_Create(void);
UtListHead_t *UtList_Create(uint32 NumTags);

/* Frees a list head created by UtList_Create. */
void UtList_Destroy(UtListHead_t *ListHead);

/* Deletes all nodes on the list. */
void UtList_Reset(UtListHead_t *ListHead);
void UtList_Reset(UtListNode_t *TagHead);

/* Merge two lists heads together */
void UtList_Merge(UtListNode_t *TagHead1, UtListNode_t *TagHead2);

/* Dynamically adds a new node to the list. Nodes are always added to the end of the list. Memory is dynamically
* allocated for the new node and to hold the data pointed to by Data. A Tag field is also provided to be used to
* store user defined information with the node. */
void UtList_Add(UtListHead_t *ListHead, void *Data, uint32 DataSize, uint32 Tag);

/* Deletes the first node from the list. */
void UtList_DeleteFirst(UtListHead_t *ListHead);

/* Deletes the last node from the list. */
void UtList_DeleteLast(UtListHead_t *ListHead);

/* Deletes the specified node from the list, this will screw up if you do not pass in a valid DeleteNode. I do not
* verify that DeleteNode is a member of the list. */
void UtList_DeleteNode(UtListHead_t *ListHead, UtListNode_t *DeleteNode);

/* Removes the first node from the list by first copying the data from the node to the memory buffer pointed to by the
* specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a
* memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */
void UtList_RemoveFirst(UtListHead_t *ListHead, void *Data);
void UtList_DeleteNode(UtListNode_t *DeleteNode);

/* Removes the last node from the list by first copying the data from the node to the memory buffer pointed to by the
* specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a
* memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */
void UtList_RemoveLast(UtListHead_t *ListHead, void *Data);

/* Removes the speciified RemoveNode from the list by first copying the data from the node to the memory buffer pointed to by the
* specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a
* memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */
void UtList_RemoveNode(UtListHead_t *ListHead, void *Data, UtListNode_t *RemoveNode);
/* Returns true if the list is empty. This is the same as (UtListHead->NumberOfEntries == 0). */
bool UtList_IsEmpty(UtListNode_t *TagHead);

/* Returns a pointer to the first node on the list. This is the same as (UtListHead->First). */
UtListNode_t *UtList_First(UtListHead_t *ListHead);
/* Returns the head node of a list for the given tag */
UtListNode_t *UtList_GetHead(UtListHead_t *ListHead, uint32 Tag);

/* Returns a pointer to the last node on the list. This is the same as (UtListHead->Last). */
UtListNode_t *UtList_Last(UtListHead_t *ListHead);
/* Returns the next node in the list, given the current node */
UtListNode_t *UtList_GetNext(UtListNode_t *ListNode);

/* Returns true if the list is empty. This is the same as (UtListHead->NumberOfEntries == 0). */
bool UtList_IsEmpty(UtListHead_t *ListHead);
/* Returns the data object associated with the current node */
void *UtList_GetObject(UtListNode_t *ListNode);

/* Returns the number of nodes on the list. This is the same as (UtListHead->NumberOfEntries). */
uint32 UtList_Depth(UtListHead_t *ListHead);
/* Check if the current node marks the end of the list */
bool UtList_IsEnd(UtListNode_t *TagHead, UtListNode_t *ListNode);

#endif
23 changes: 23 additions & 0 deletions ut_assert/inc/uttest.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@
*/
void UtTest_Add(void (*Test)(void), void (*Setup)(void), void (*Teardown)(void), const char *TestName);

/**
* \brief Registers a setup function
*
* This group of functions are invoked BEFORE normal test routines added with UtTest_Add.
* Within the group, functions are executed in the order registered.
*
* \param Setup Setup function, called before the test function
* \param TestName Name of function for logging purposes
*/
void UtTest_AddSetup(void (*Setup)(void), const char *SequenceName);

/**
* \brief Registers a teardown function
*
* This group of functions is invoked AFTER normal test routines added with UtTest_Add.
* Within the group, functions are executed in the order registered.
*
* \param Teardown Teardown function, called before the test function
* \param TestName Name of function for logging purposes
*/
void UtTest_AddTeardown(void (*Teardown)(void), const char *SequenceName);


/**
* \brief Early initialization function
*
Expand Down
2 changes: 1 addition & 1 deletion ut_assert/src/utbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void OS_Application_Run(void)
*/
void OS_Application_Startup(void)
{

UtTest_EarlyInit();
UT_BSP_Setup();

/*
Expand Down
2 changes: 1 addition & 1 deletion ut_assert/src/utglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ typedef struct

typedef struct
{
UtListHead_t DataBase;
UtListHead_t *DataBasePtr;
uint32 ExecutedCount;
} UtAssert_Global_t;

Expand Down
201 changes: 114 additions & 87 deletions ut_assert/src/utlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,138 +37,165 @@
* Function Definitions
*/

UtListHead_t *UtList_Create(void)
UtListHead_t *UtList_Create(uint32 NumTags)
{
UtListHead_t *NewList;
struct ListAllocator
{
UtListHead_t Head;
UtListNode_t Tags[];
};
struct ListAllocator *NewList;
UtListNode_t *TagHead;
size_t ActualSize;
uint32 i;

ActualSize = sizeof(struct ListAllocator) + (sizeof(UtListNode_t) * NumTags);
NewList = (struct ListAllocator *)malloc(ActualSize);

memset(NewList, 0, ActualSize);

NewList->Head.Tags = NewList->Tags;
NewList->Head.NumberOfTags = NumTags;

for (i=0; i < NumTags; ++i)
{
TagHead = &NewList->Head.Tags[i];
TagHead->Tag = i;
TagHead->Next = TagHead;
TagHead->Prev = TagHead;
}

NewList = malloc(sizeof(UtListHead_t));
NewList->First = NULL;
NewList->Last = NULL;
NewList->NumberOfEntries = 0;
return (NewList);
return (&NewList->Head);
}

void UtList_Destroy(UtListHead_t *ListHead)
{
UtList_Reset(ListHead);
uint32 i;

for (i=0; i < ListHead->NumberOfTags; ++i)
{
UtList_Reset(&ListHead->Tags[i]);
}
free(ListHead);
}

void UtList_Reset(UtListHead_t *ListHead)
void UtList_Reset(UtListNode_t *TagHead)
{
while (!UtList_IsEmpty(ListHead)) {
UtList_DeleteFirst(ListHead);
while (!UtList_IsEmpty(TagHead))
{
UtList_DeleteNode(TagHead->Next);
}
}

void UtList_Add(UtListHead_t *ListHead, void *Data, uint32 DataSize, uint32 Tag)
void UtList_Merge(UtListNode_t *TagHead1, UtListNode_t *TagHead2)
{
UtListNode_t *NewNode = NULL;

NewNode = malloc(sizeof(UtListNode_t));
if (ListHead->NumberOfEntries == 0) {

ListHead->First = NewNode;
ListHead->Last = NewNode;
ListHead->NumberOfEntries++;
UtListNode_t *Tail1 = TagHead1->Prev;
UtListNode_t *Tail2 = TagHead2->Prev;

NewNode->Next = NULL;
NewNode->Prev = NULL;
NewNode->Tag = Tag;
NewNode->DataSize = DataSize;
NewNode->Data = malloc(DataSize);
memcpy(NewNode->Data, Data, DataSize);
}
else {
Tail1->Next = TagHead2;
Tail2->Next = TagHead1;
TagHead1->Prev = Tail2;
TagHead2->Prev = Tail1;
}

NewNode->Next = NULL;
NewNode->Prev = ListHead->Last;
NewNode->Tag = Tag;
NewNode->DataSize = DataSize;
NewNode->Data = malloc(DataSize);
memcpy(NewNode->Data, Data, DataSize);
void UtList_Insert_After(UtListNode_t *ExistingNode, UtListNode_t *NewNode)
{
NewNode->Next = ExistingNode->Next;
NewNode->Prev = ExistingNode;
NewNode->Prev->Next = NewNode;
NewNode->Next->Prev = NewNode;
}

ListHead->Last->Next = NewNode;
ListHead->Last = NewNode;
ListHead->NumberOfEntries++;
}
void UtList_Insert_Before(UtListNode_t *ExistingNode, UtListNode_t *NewNode)
{
NewNode->Next = ExistingNode;
NewNode->Prev = ExistingNode->Prev;
NewNode->Prev->Next = NewNode;
NewNode->Next->Prev = NewNode;
}

void UtList_DeleteFirst(UtListHead_t *ListHead)
void UtList_Extract(UtListNode_t *ExistingNode)
{
UtList_DeleteNode(ListHead, ListHead->First);
ExistingNode->Next->Prev = ExistingNode->Prev;
ExistingNode->Prev->Next = ExistingNode->Next;
ExistingNode->Next = ExistingNode;
ExistingNode->Prev = ExistingNode;
}

void UtList_DeleteLast(UtListHead_t *ListHead)
UtListNode_t *UtList_NewNode(void *Data, uint32 DataSize)
{
UtList_DeleteNode(ListHead, ListHead->Last);
union NodeAllocator
{
UtListNode_t Node;
double AlignDbl;
void* AlignPtr;
long AlignLong;
} *AllocNode;

AllocNode = malloc(sizeof(union NodeAllocator) + DataSize);
memset(AllocNode, 0, sizeof(union NodeAllocator));
AllocNode->Node.Data = &AllocNode[1];
AllocNode->Node.DataSize = DataSize;
memcpy(AllocNode->Node.Data, Data, DataSize);

AllocNode->Node.Next = &AllocNode->Node;
AllocNode->Node.Prev = &AllocNode->Node;

return &AllocNode->Node;
}

void UtList_DeleteNode(UtListHead_t *ListHead, UtListNode_t *DeleteNode)

void UtList_Add(UtListHead_t *ListHead, void *Data, uint32 DataSize, uint32 Tag)
{

if (!UtList_IsEmpty(ListHead)) {

if (ListHead->NumberOfEntries == 1) {
ListHead->First = NULL;
ListHead->Last = NULL;
ListHead->NumberOfEntries = 0;
}
else if (DeleteNode == ListHead->First) {
ListHead->First = DeleteNode->Next;
ListHead->First->Prev = NULL;
ListHead->NumberOfEntries--;
}
else if (DeleteNode == ListHead->Last) {
ListHead->Last = DeleteNode->Prev;
ListHead->Last->Next = NULL;
ListHead->NumberOfEntries--;
}
else {
DeleteNode->Prev->Next = DeleteNode->Next;
DeleteNode->Next->Prev = DeleteNode->Prev;
ListHead->NumberOfEntries--;
}

free(DeleteNode->Data);
free(DeleteNode);
UtListNode_t *TagHead;
UtListNode_t *NewNode;

TagHead = UtList_GetHead(ListHead, Tag);
if (TagHead != NULL)
{
NewNode = UtList_NewNode(Data, DataSize);
NewNode->Tag = Tag;
UtList_Insert_Before(TagHead, NewNode);
}
}

void UtList_RemoveFirst(UtListHead_t *ListHead, void *Data)
void UtList_DeleteNode(UtListNode_t *DeleteNode)
{
UtList_RemoveNode(ListHead, Data, ListHead->First);
UtList_Extract(DeleteNode);

/* non-data/header nodes shouldn't be free()'ed */
if (DeleteNode->Data != NULL)
{
free(DeleteNode);
}
}

void UtList_RemoveLast(UtListHead_t *ListHead, void *Data)
bool UtList_IsEmpty(UtListNode_t *TagHead)
{
UtList_RemoveNode(ListHead, Data, ListHead->Last);
return(TagHead->Next == TagHead);
}

void UtList_RemoveNode(UtListHead_t *ListHead, void *Data, UtListNode_t *CurrentNode)
UtListNode_t *UtList_GetHead(UtListHead_t *ListHead, uint32 Tag)
{
if (!UtList_IsEmpty(ListHead)) {
memcpy(Data, CurrentNode->Data, CurrentNode->DataSize);
UtList_DeleteNode(ListHead, CurrentNode);
if (Tag >= ListHead->NumberOfTags)
{
return NULL;
}
return &ListHead->Tags[Tag];
}

UtListNode_t *UtList_First(UtListHead_t *ListHead)
UtListNode_t *UtList_GetNext(UtListNode_t *ListNode)
{
return(ListHead->First);
return ListNode->Next;
}

UtListNode_t *UtList_Last(UtListHead_t *ListHead)
void *UtList_GetObject(UtListNode_t *ListNode)
{
return(ListHead->Last);
return ListNode->Data;
}

bool UtList_IsEmpty(UtListHead_t *ListHead)
bool UtList_IsEnd(UtListNode_t *TagHead, UtListNode_t *ListNode)
{
return(ListHead->NumberOfEntries == 0);
return(TagHead == ListNode);
}

uint32 UtList_Depth(UtListHead_t *ListHead)
{
return(ListHead->NumberOfEntries);
}
Loading

0 comments on commit 9a9171c

Please sign in to comment.