2020-01-20 19:52:46 -06:00
// 10 april 2019
# include "test.h"
2020-01-21 13:19:52 -06:00
# include "thread.h"
2020-05-09 01:04:51 -05:00
# include "../common/testhooks.h"
2020-01-20 19:52:46 -06:00
// TODO test the number of calls to queued functions made
2020-05-09 19:03:51 -05:00
static void testImplInitFailureFull ( const char * file , long line )
2020-05-09 01:04:51 -05:00
{
uiInitError err ;
2020-05-09 01:33:18 -05:00
void * ctx ;
2020-05-09 01:04:51 -05:00
2020-05-09 01:33:18 -05:00
ctx = beginCheckProgrammerError ( NULL ) ;
2020-05-09 01:04:51 -05:00
uiprivTestHookSetInitShouldFailArtificially ( true ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() succeeded; expected failure " ) ;
2020-05-09 01:04:51 -05:00
else if ( strcmp ( err . Message , " general failure " ) ! = 0 )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() failed with wrong message: " diff ( " %s " ) ,
2020-05-09 01:04:51 -05:00
err . Message , " general failure " ) ;
2020-05-09 01:33:18 -05:00
endCheckProgrammerError ( ctx ) ;
2020-05-09 01:04:51 -05:00
}
2020-05-09 19:03:51 -05:00
# define testImplInitFailure() testImplInitFailureFull(__FILE__, __LINE__)
2020-05-09 15:35:01 -05:00
TestNoInit ( InitFailure )
{
testImplInitFailure ( ) ;
}
2020-05-09 19:03:51 -05:00
static void testImplNonNullOptionsFull ( const char * file , long line )
2020-05-09 00:45:09 -05:00
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): invalid uiInitOptions passed " ) ;
if ( uiInit ( ctx , NULL ) )
2020-05-09 19:03:51 -05:00
TestErrorfFull ( file , line , " uiInit() with non-NULL options succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 19:03:51 -05:00
# define testImplNonNullOptions() testImplNonNullOptionsFull(__FILE__, __LINE__)
2020-05-09 15:35:01 -05:00
TestNoInit ( InitWithNonNullOptionsIsProgrammerError )
{
testImplNonNullOptions ( ) ;
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitWithNullErrorIsProgrammerError )
2020-01-20 19:52:46 -06:00
{
2020-05-09 00:45:09 -05:00
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): invalid null pointer for uiInitError " ) ;
2020-01-20 19:52:46 -06:00
if ( uiInit ( NULL , NULL ) )
TestErrorf ( " uiInit() with NULL error succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
TestNoInit ( InitWithWrongErrorSizeIsProgrammerError )
{
uiInitError err ;
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): wrong size 2 for uiInitError " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
2020-01-20 19:52:46 -06:00
err . Size = 2 ;
if ( uiInit ( NULL , & err ) )
TestErrorf ( " uiInit() with error with invalid size succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
Test ( InitCorrectlyAfterInitializedSuccessfully )
{
uiInitError err ;
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
2020-01-20 19:52:46 -06:00
err . Size = sizeof ( uiInitError ) ;
2020-05-09 00:45:09 -05:00
if ( uiInit ( NULL , & err ) )
TestFatalf ( " uiInit() after a previous successful call succeeded; expected failure " ) ;
endCheckProgrammerError ( ctx ) ;
}
2020-01-20 19:52:46 -06:00
2020-05-09 00:45:09 -05:00
Test ( InitIncorrectlyAfterInitializedSuccessfully )
{
void * ctx ;
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
TestFatalf ( " bad uiInit() after a previous successful call succeeded; expected failure " ) ;
endCheckProgrammerError ( ctx ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 01:38:07 -05:00
TestNoInit ( InitCorrectlyAfterFailureToInitialize )
{
uiInitError err ;
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplInitFailure ( ) ;
2020-05-09 01:38:07 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " uiInit() after a previous failed call succeeded; expected failure " ) ;
2020-05-09 01:38:07 -05:00
endCheckProgrammerError ( ctx ) ;
}
TestNoInit ( InitIncorrectlyAfterFailureToInitialize )
{
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplInitFailure ( ) ;
2020-05-09 01:38:07 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " bad uiInit() after a previous failed call succeeded; expected failure " ) ;
2020-05-09 01:38:07 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitCorrectlyAfterIncorrectInitialization )
2020-01-20 19:52:46 -06:00
{
uiInitError err ;
2020-05-09 00:45:09 -05:00
void * ctx ;
2020-01-20 19:52:46 -06:00
2020-05-09 15:35:01 -05:00
testImplNonNullOptions ( ) ;
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
2020-01-20 19:52:46 -06:00
memset ( & err , 0 , sizeof ( uiInitError ) ) ;
err . Size = sizeof ( uiInitError ) ;
if ( uiInit ( NULL , & err ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " uiInit() after a previous erroneous call succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 00:45:09 -05:00
TestNoInit ( InitIncorrectlyAfterIncorrectInitialization )
{
void * ctx ;
2020-05-09 15:35:01 -05:00
testImplNonNullOptions ( ) ;
2020-05-09 00:45:09 -05:00
ctx = beginCheckProgrammerError ( " uiInit(): attempt to call more than once " ) ;
if ( uiInit ( NULL , NULL ) )
2020-05-09 15:35:01 -05:00
TestFatalf ( " bad uiInit() after a previous erroneous call succeeded; expected failure " ) ;
2020-05-09 00:45:09 -05:00
endCheckProgrammerError ( ctx ) ;
}
2020-05-09 15:54:18 -05:00
struct testQueueMainParams {
unsigned int n ;
2020-01-21 14:13:24 -06:00
threadSysError err ;
2020-01-20 19:52:46 -06:00
} ;
static void queued ( void * data )
{
2020-05-09 15:54:18 -05:00
struct testQueueMainParams * p = ( struct testQueueMainParams * ) data ;
2020-01-20 19:52:46 -06:00
2020-05-09 15:54:18 -05:00
p - > n + + ;
if ( p - > n > 2 )
p - > n = 2 ;
2020-01-20 19:52:46 -06:00
uiQuit ( ) ;
}
2020-01-21 13:19:52 -06:00
Test ( QueueMain )
2020-01-20 19:52:46 -06:00
{
2020-05-09 15:54:18 -05:00
struct testQueueMainParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 15:54:18 -05:00
memset ( & p , 0 , sizeof ( struct testQueueMainParams ) ) ;
p . n = 0 ;
2020-01-20 19:52:46 -06:00
uiQueueMain ( queued , & p ) ;
2020-01-21 13:19:52 -06:00
uiMain ( ) ;
2020-05-09 15:54:18 -05:00
switch ( p . n ) {
case 0 :
TestErrorf ( " uiQueueMain() function was not called " ) ;
break ;
case 1 :
// do nothing; this is the expected case
break ;
default :
TestErrorf ( " uiQueueMain() called more than once " ) ;
}
2020-01-20 19:52:46 -06:00
}
2020-05-09 15:54:18 -05:00
// TODOTODOTODOTODOTODOTODOTODOTODOTODOTODO
2020-05-09 19:03:51 -05:00
struct queuedOrder {
int calls [ 4 ] ;
int i ;
unsigned int extraCalls ;
} ;
2020-05-09 15:54:18 -05:00
2020-05-09 19:03:51 -05:00
static void queueOrder ( struct queuedOrder * q , int n )
{
if ( q - > i < 4 ) {
q - > calls [ q - > i ] = n ;
q - > i + + ;
return ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 19:03:51 -05:00
q - > extraCalls + + ;
if ( q - > extraCalls > 9 )
q - > extraCalls = 9 ;
}
2020-05-09 20:54:26 -05:00
static void queueCheckOrderFull ( const char * file , long line , struct queuedOrder * got , int wantI , int wantA , int wantB , int wantC , int wantD )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
int wantarr [ 4 ] ;
int i ;
if ( got - > i ! = wantI | | got - > extraCalls ! = 0 ) {
const char * orMore ;
orMore = " " ;
if ( got - > extraCalls > = 9 )
orMore = " or more " ;
TestErrorfFull ( file , line , " wrong number of queued function calls: " diff ( " %d%s " ) ,
got - > i + got - > extraCalls , orMore ,
wantI , " " ) ;
}
wantarr [ 0 ] = wantA ;
wantarr [ 1 ] = wantB ;
wantarr [ 2 ] = wantC ;
wantarr [ 3 ] = wantD ;
for ( i = 0 ; i < 4 ; i + + )
if ( got - > calls [ i ] ! = wantarr [ i ] )
TestErrorfFull ( file , line , " wrong value for call %d in sequence: " diff ( " %d " ) ,
i + 1 , got - > calls [ i ] , wantarr [ i ] ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
# define queueCheckOrder(got, i, a, b, c, d) queueCheckOrderFull(__FILE__, __LINE__, got, i, a, b, c, d)
struct queueTestParams {
struct queuedOrder order1 ;
struct queuedOrder order2 ;
2020-01-20 19:52:46 -06:00
} ;
2020-05-09 20:54:26 -05:00
# define queueStep(name, type, field, n) \
static void name ( void * data ) \
{ \
type * p = ( type * ) data ; \
queueOrder ( & ( p - > field ) , n ) ; \
}
queueStep ( step11 , struct queueTestParams , order1 , 1 )
queueStep ( step12 , struct queueTestParams , order1 , 2 )
queueStep ( step13 , struct queueTestParams , order1 , 3 )
queueStep ( step14 , struct queueTestParams , order1 , 4 )
queueStep ( step21 , struct queueTestParams , order2 , 1 )
queueStep ( step22 , struct queueTestParams , order2 , 2 )
queueStep ( step23 , struct queueTestParams , order2 , 3 )
queueStep ( step24 , struct queueTestParams , order2 , 4 )
static void done ( void * data )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
uiQuit ( ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
static void queueOrder1 ( struct queueTestParams * p )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
uiQueueMain ( step11 , p ) ;
uiQueueMain ( step12 , p ) ;
uiQueueMain ( step13 , p ) ;
uiQueueMain ( step14 , p ) ;
uiQueueMain ( done , NULL ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
Test ( QueueMain_Sequence )
2020-01-20 19:52:46 -06:00
{
2020-05-09 20:54:26 -05:00
struct queueTestParams p ;
2020-01-20 19:52:46 -06:00
2020-05-09 20:54:26 -05:00
memset ( & p , 0 , sizeof ( struct queueTestParams ) ) ;
queueOrder1 ( & p ) ;
2020-01-21 13:19:52 -06:00
uiMain ( ) ;
2020-05-09 20:54:26 -05:00
queueCheckOrder ( & ( p . order1 ) , 4 , 1 , 2 , 3 , 4 ) ;
2020-01-20 19:52:46 -06:00
}
2020-05-09 20:54:26 -05:00
#if 0
2020-01-21 13:19:52 -06:00
// TODO make a version of these where the thread is started by a queued function
2020-01-20 19:52:46 -06:00
static void queueThread ( void * data )
{
struct testParams * p = ( struct testParams * ) data ;
2020-01-21 14:13:24 -06:00
p - > err = threadSleep ( 1250 * threadMillisecond ) ;
2020-01-20 19:52:46 -06:00
uiQueueMain ( queued , p ) ;
}
2020-05-09 19:03:51 -05:00
TODOTest ( QueueMain_DifferentThread )
2020-01-20 19:52:46 -06:00
{
threadThread * thread ;
threadSysError err ;
struct testParams p ;
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
p . flag = 0 ;
err = threadNewThread ( queueThread , & p , & thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
uiMain ( ) ;
2020-01-20 19:52:46 -06:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2020-01-21 14:13:24 -06:00
if ( p . err ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . err ) ) ;
2020-01-20 19:52:46 -06:00
if ( p . flag ! = 1 )
2020-01-21 13:19:52 -06:00
TestErrorf ( " uiQueueMain() didn't set flag properly: " diff ( " %d " ) ,
2020-01-20 19:52:46 -06:00
p . flag , 1 ) ;
}
static void queueOrderThread ( void * data )
{
struct testParams * p = ( struct testParams * ) data ;
2020-01-21 14:13:24 -06:00
p - > err = threadSleep ( 1250 * threadMillisecond ) ;
2020-01-20 19:52:46 -06:00
queueOrder ( p ) ;
}
2020-05-09 19:03:51 -05:00
TODOTest ( QueueMain_DifferentThreadSequence )
2020-01-20 19:52:46 -06:00
{
threadThread * thread ;
threadSysError err ;
struct testParams p ;
memset ( & p , 0 , sizeof ( struct testParams ) ) ;
p . flag = 1 ; // make sure it's initialized just in case
err = threadNewThread ( queueOrderThread , & p , & thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error creating thread: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
uiMain ( ) ;
2020-01-20 19:52:46 -06:00
err = threadThreadWaitAndFree ( thread ) ;
if ( err ! = 0 )
2020-01-21 13:19:52 -06:00
TestFatalf ( " error waiting for thread to finish: " threadSysErrorFmt , threadSysErrorFmtArg ( err ) ) ;
2020-01-21 14:13:24 -06:00
if ( p . err ! = 0 )
TestErrorf ( " error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " threadSysErrorFmt , threadSysErrorFmtArg ( p . err ) ) ;
2020-01-21 13:19:52 -06:00
checkOrder ( p . flag ) ;
2020-01-20 19:52:46 -06:00
}
2020-01-21 13:19:52 -06:00
#if 0
2020-01-20 19:52:46 -06:00
static void timer ( void * data )
{
int * n = ( int * ) data ;
// TODO return stop if n == 5, continue otherwise
* n + + ;
}
testingTest ( Timer )
{
}
# endif
2020-05-09 15:54:18 -05:00
# endif