Added a facility to do timeouts in test functions. Also started cleaning up the weird TimerNsec abstractions.

This commit is contained in:
Pietro Gagliardi 2019-04-28 13:12:40 -04:00
parent 9c70782a0f
commit 1bc2297597
7 changed files with 91 additions and 16 deletions

View File

@ -1,7 +1,6 @@
// 10 april 2019
#include <string.h>
#include "../ui.h"
#include "testing.h"
#include "test.h"
// TODO fix up the formatting of testing.c so we can use newlines on the got/want stuff
@ -60,7 +59,7 @@ testingTest(QueueMain)
int flag = 0;
uiQueueMain(queued, &flag);
uiMain();
timeout_uiMain(t, 5 * testingTimerNsecPerSec, 0);
if (flag != 1)
testingTErrorf(t, "uiQueueMain didn't set flag properly: got %d, want 1", flag);
}

View File

@ -1,5 +1,17 @@
// 10 april 2019
#include "testing.h"
#include "test.h"
static void timeoutMain(testingT *t, void *data)
{
uiMain();
}
void timeout_uiMain(testingT *t, int64_t timeout, int failNowOnError)
{
testingRunWithTimeout(t, timeout,
timeoutMain, NULL,
"uiMain()", failNowOnError);
}
int main(void)
{

View File

@ -9,9 +9,15 @@ libui_test_sources = [
if libui_OS == 'windows'
libui_test_sources += ['testing_windows.c']
elif libui_OS == 'darwin'
libui_test_sources += ['testing_darwin.c']
libui_test_sources += [
'testing_darwin.c',
'testing_darwinunix.c',
]
else
libui_test_sources += ['testing_unix.c']
libui_test_sources += [
'testing_darwinunix.c',
'testing_unix.c',
]
endif
libui_test_deps = []

6
test/test.h Normal file
View File

@ -0,0 +1,6 @@
// 28 april 2019
#include "../ui.h"
#include "testing.h"
// main.c
extern void timeout_uiMain(testingT *t, int64_t timeout, int failNowOnError);

View File

@ -148,9 +148,9 @@ static void testsetRun(struct testset *set, int *anyFailed)
} else if (t->skipped)
// note that failed overrides skipped
status = "SKIP";
timerstr = testingTimerString(timer);
timerstr = testingTimerNsecString(testingTimerNsec(timer));
printf("--- %s: %s (%s)\n", status, t->name, timerstr);
testingFreeTimerString(timerstr);
testingFreeTimerNsecString(timerstr);
t++;
}
testingFreeTimer(timer);
@ -221,13 +221,13 @@ static void returnNow(testingT *t)
}
}
void testingprivTFailNow(testingT *t)
void testingTFailNow(testingT *t)
{
testingTFail(t);
returnNow(t);
}
void testingprivTSkipNow(testingT *t)
void testingTSkipNow(testingT *t)
{
t->skipped = 1;
returnNow(t);
@ -306,9 +306,8 @@ static void fillIntPart(char *s, int *start, uint64_t unsec)
}
}
char *testingTimerString(testingTimer *t)
char *testingTimerNsecString(int64_t nsec)
{
int64_t nsec;
uint64_t unsec;
int neg;
char *s;
@ -321,7 +320,6 @@ char *testingTimerString(testingTimer *t)
memset(s, 0, 33 * sizeof (char));
start = 32;
nsec = testingTimerNsec(t);
if (nsec == 0) {
s[0] = '0';
s[1] = 's';
@ -368,7 +366,7 @@ char *testingTimerString(testingTimer *t)
return s;
}
void testingFreeTimerString(char *s)
void testingFreeTimerNsecString(char *s)
{
free(s);
}

View File

@ -66,6 +66,7 @@ extern void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void
typedef struct testingTimer testingTimer;
#define testingTimerNsecPerUsec ((int64_t) 1000)
#define testingTimerNsecPerSec ((int64_t) 1000000000)
extern testingTimer *testingNewTimer(void);
@ -73,8 +74,11 @@ extern void testingFreeTimer(testingTimer *t);
extern void testingTimerStart(testingTimer *t);
extern void testingTimerEnd(testingTimer *t);
extern int64_t testingTimerNsec(testingTimer *t);
extern char *testingTimerString(testingTimer *t);
extern void testingFreeTimerString(char *s);
extern char *testingTimerNsecString(int64_t nsec);
extern void testingFreeTimerNsecString(char *s);
extern void testingRunWithTimeout(testingT *t, int64_t timeout, void (*f)(testingT *t, void *data), void *data, const char *comment, int failNowOnError);
extern void testingprivRegisterTest(const char *, void (*)(testingT *), const char *, long);
extern void testingprivRegisterTestBefore(const char *, void (*)(testingT *), const char *, long);

50
test/testing_darwinunix.c Normal file
View File

@ -0,0 +1,50 @@
// 28 april 2019
#include <errno.h>
#include <inttypes.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include "testing.h"
static jmp_buf timeout_ret;
static void onTimeout(int sig)
{
longjmp(timeout_ret, 1);
}
void testingRunWithTimeout(testingT *t, int64_t timeout, void (*f)(testingT *t, void *data), void *data, const char *comment, int failNowOnError)
{
char *timeoutstr;
sig_t prevsig;
struct itimerval timer, prevtimer;
int setitimerError = 0;
timeoutstr = testingTimerNsecString(timeout);
prevsig = signal(SIGALRM, onTimeout);
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
timer.it_value.tv_sec = timeout / testingTimerNsecPerSec;
timer.it_value.tv_usec = (timeout % testingTimerNsecPerSec) / testingTimerNsecPerUsec;
if (setitimer(ITIMER_REAL, &timer, &prevtimer) != 0) {
setitimerError = errno;
testingTErrorf(t, "error applying %s timeout: %s", comment, strerror(setitimerError));
goto out;
}
if (setjmp(timeout_ret) == 0) {
(*f)(t, data);
failNowOnError = 0; // we succeeded
} else
testingTErrorf(t, "%s timeout passed (%s)", comment, timeoutstr);
out:
if (setitimerError == 0)
setitimer(ITIMER_REAL, &prevtimer, NULL);
signal(SIGALRM, prevsig);
testingFreeTimerNsecString(timeoutstr);
if (failNowOnError)
testingTFailNow(t);
}