Added a facility to do timeouts in test functions. Also started cleaning up the weird TimerNsec abstractions.
This commit is contained in:
parent
9c70782a0f
commit
1bc2297597
|
@ -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);
|
||||
}
|
||||
|
|
14
test/main.c
14
test/main.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 = []
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue