Provided a mechanism for the testing library to abort on an internal error; redefined memory allocation to do so. This will also be used for resolving many of the TODOs on the Windows testing code.

This commit is contained in:
Pietro Gagliardi 2019-04-29 23:46:08 -04:00
parent 559e4bc139
commit db6b6fd97b
6 changed files with 64 additions and 39 deletions

View File

@ -4,8 +4,45 @@
#include <setjmp.h>
#include <string.h>
#include "testing.h"
#include "testingpriv.h"
#define testingprivNew(T) ((T *) malloc(sizeof (T)))
void testingprivInternalError(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "** testing internal error: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "; aborting\n");
va_end(ap);
abort();
}
void *testingprivMalloc(size_t n, const char *what)
{
void *x;
x = malloc(n);
if (x == NULL)
testingprivInternalError("memory exhausted allocating %s", what);
memset(x, 0, n);
return x;
}
void *testingprivRealloc(void *x, size_t n, const char *what)
{
void *y;
y = realloc(x, n);
if (y == NULL)
testingprivInternalError("memory exhausted reallocating %s", what);
return y;
}
void testingprivFree(void *x)
{
free(x);
}
struct defer {
void (*f)(testingT *, void *);
@ -65,12 +102,8 @@ static struct testset testsAfter = { NULL, 0, 0 };
static void testsetAdd(struct testset *set, const char *name, void (*f)(testingT *), const char *file, long line)
{
if (set->len == set->cap) {
testingT *newbuf;
set->cap += nGrow;
newbuf = (testingT *) realloc(set->tests, set->cap * sizeof (testingT));
// TODO abort if newbuf is NULL
set->tests = newbuf;
set->tests = testingprivResizeArray(set->tests, testingT, set->cap);
}
initTest(set->tests + set->len, name, f, file, line);
set->len++;
@ -315,9 +348,7 @@ char *testingNsecString(int64_t nsec)
const struct timerStringPart *p;
// The Go algorithm says 32 should be enough.
s = (char *) malloc(33 * sizeof (char));
// TODO handle failure
memset(s, 0, 33 * sizeof (char));
s = testingprivNewArray(char, 33);
start = 32;
if (nsec == 0) {
@ -376,5 +407,5 @@ char *testingNsecString(int64_t nsec)
void testingFreeNsecString(char *s)
{
free(s);
testingprivFree(s);
}

View File

@ -4,6 +4,7 @@
#include <mach/mach.h>
#include <mach/mach_time.h>
#include "testing.h"
#include "testingpriv.h"
struct testingTimer {
uint64_t start;
@ -12,17 +13,12 @@ struct testingTimer {
testingTimer *testingNewTimer(void)
{
testingTimer *t;
t = (testingTimer *) malloc(sizeof (testingTimer));
// TODO handle failure
memset(t, 0, sizeof (testingTimer));
return t;
return testingprivNew(testingTimer);
}
void testingFreeTimer(testingTimer *t)
{
free(t);
testingprivFree(t);
}
void testingTimerStart(testingTimer *t)

View File

@ -9,6 +9,7 @@
#include <sys/time.h>
#include <pthread.h>
#include "testing.h"
#include "testingpriv.h"
// TODO don't start the timer on any platform until after we call setjmp(); also decide whether to start the timer before or after resuming the thread on Windows
@ -85,9 +86,7 @@ testingThread *testingNewThread(void (*f)(void *data), void *data)
{
testingThread *t;
t = malloc(sizeof (testingThread));
// TODO check error
memset(t, 0, sizeof (testingThread));
t = testingprivNew(testingThread);
t->f = f;
t->data = data;
@ -102,5 +101,5 @@ void testingThreadWaitAndFree(testingThread *t)
pthread_join(t->thread, NULL);
// TODO end check errors
// TODO do we need to free t->thread somehow?
free(t);
testingprivFree(t);
}

View File

@ -3,6 +3,7 @@
#include <string.h>
#include <time.h>
#include "testing.h"
#include "testingpriv.h"
struct testingTimer {
struct timespec start;
@ -11,17 +12,12 @@ struct testingTimer {
testingTimer *testingNewTimer(void)
{
testingTimer *t;
t = (testingTimer *) malloc(sizeof (testingTimer));
// TODO handle failure
memset(t, 0, sizeof (testingTimer));
return t;
return testingprivNew(testingTimer);
}
void testingFreeTimer(testingTimer *t)
{
free(t);
testingprivFree(t);
}
void testingTimerStart(testingTimer *t)

View File

@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
#include "testing.h"
#include "testingpriv.h"
struct testingTimer {
LARGE_INTEGER start;
@ -24,17 +25,12 @@ struct testingTimer {
testingTimer *testingNewTimer(void)
{
testingTimer *t;
t = (testingTimer *) malloc(sizeof (testingTimer));
// TODO handle failure
memset(t, 0, sizeof (testingTimer));
return t;
return testingprivNew(testingTimer);
}
void testingFreeTimer(testingTimer *t)
{
free(t);
testingprivFree(t);
}
void testingTimerStart(testingTimer *t)
@ -288,9 +284,7 @@ testingThread *testingNewThread(void (*f)(void *data), void *data)
{
testingThread *t;
t = malloc(sizeof (testingThread));
// TODO check error
ZeroMemory(t, sizeof (testingThread));
t = testingprivNew(testingThread);
t->f = f;
t->data = data;
@ -305,5 +299,5 @@ void testingThreadWaitAndFree(testingThread *t)
WaitForSingleObject((HANDLE) (t->handle), INFINITE);
// TODO end check errors
CloseHandle((HANDLE) (t->handle));
free(t);
testingprivFree(t);
}

9
test/testingpriv.h Normal file
View File

@ -0,0 +1,9 @@
// 29 april 2019
extern void testingprivInternalError(const char *fmt, ...);
extern void *testingprivMalloc(size_t n, const char *what);
#define testingprivNew(T) ((T *) testingprivMalloc(sizeof (T), #T))
#define testingprivNewArray(T, n) ((T *) testingprivMalloc(n * sizeof (T), #T "[" #n "]"))
extern void *testingprivRealloc(void *x, size_t n, const char *what);
#define testingprivResizeArray(x, T, n) ((T *) testingprivRealloc(x, n * sizeof (T), #T "[" #n "]"))
extern void testingprivFree(void *x);