Converted some of the test routines to use the new epicsUnitTest facility.

This commit is contained in:
Andrew Johnson
2006-03-30 20:13:25 +00:00
parent 97a5aa16a0
commit 4d67f3596a
10 changed files with 357 additions and 396 deletions

View File

@@ -13,25 +13,39 @@ include $(TOP)/configure/CONFIG
PROD_LIBS += Com
epicsUnitTestTest_SRCS += epicsUnitTestTest.c
PROD_HOST += epicsUnitTestTest
TESTS += epicsUnitTestTest
epicsCalcTest_SRCS += epicsCalcTest.cpp
PROD_HOST += epicsCalcTest
OBJS_IOC_vxWorks += epicsCalcTest
TESTS += epicsCalcTest
epicsAlgorithmTest_SRCS += epicsAlgorithmTest.cpp
PROD_HOST += epicsAlgorithmTest
OBJS_IOC_vxWorks += epicsAlgorithmTest
TESTS += epicsAlgorithmTest
epicsMathTestHost_SRCS += epicsMathTestMain.cpp epicsMathTest.c
PROD_HOST += epicsMathTestHost
OBJS_IOC_vxWorks += epicsMathTest
TESTS += epicsMathTestHost
epicsStdioTestHost_SRCS += epicsStdioTestMain.cpp epicsStdioTest.c
PROD_HOST += epicsStdioTestHost
OBJS_IOC_vxWorks += epicsStdioTest
TESTS += epicsStdioTestHost
epicsStringTestHost_SRCS += epicsStringTestMain.cpp epicsStringTest.c
PROD_HOST += epicsStringTestHost
OBJS_IOC_vxWorks += epicsStringTest
TESTS += epicsStringTestHost
epicsTimeTestHost_SRCS += epicsTimeTestMain.cpp epicsTimeTest.cpp
PROD_HOST += epicsTimeTestHost
OBJS_IOC_vxWorks += epicsTimeTest
TESTS += epicsTimeTestHost
epicsThreadTestHost_SRCS += epicsThreadTestMain.cpp epicsThreadTest.cpp
PROD_HOST += epicsThreadTestHost
@@ -81,6 +95,7 @@ OBJS_IOC_vxWorks += epicsMutexTest
epicsExceptionTestHost_SRCS += epicsExceptionTestMain.cpp epicsExceptionTest.cpp
PROD_HOST += epicsExceptionTestHost
OBJS_IOC_vxWorks += epicsExceptionTest
TESTS += epicsExceptionTestHost
epicsMessageQueueTestHost_SRCS += epicsMessageQueueTestMain.cpp epicsMessageQueueTest.cpp
PROD_HOST += epicsMessageQueueTestHost
@@ -89,6 +104,7 @@ OBJS_IOC_vxWorks += epicsMessageQueueTest
macEnvExpandTestHost_SRCS += macEnvExpandTestMain.cpp macEnvExpandTest.c
PROD_HOST += macEnvExpandTestHost
OBJS_IOC_vxWorks += macEnvExpandTest
TESTS += macEnvExpandTestHost
blockingSockTestHost_SRCS += blockingSockTestMain.cpp blockingSockTest.cpp
PROD_HOST += blockingSockTestHost
@@ -98,10 +114,30 @@ blockingSockTestHost_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
blockingSockTestHost_SYS_LIBS_solaris = socket
#buckTest_SRCS += buckTest.c
#PROD_HOST += buckTest
#fdmgrTest_SRCS += fdmgrTest.c
#PROD_HOST += fdmgrTest
OBJS_IOC_RTEMS += $(OBJS_IOC_vxWorks)
TEST_SCRIPTS += $(TESTS:%=%.t)
include $(TOP)/configure/RULES
test: $(TEST_SCRIPTS)
@perl -e 'use Test::Harness; runtests @ARGV;' $(TEST_SCRIPTS)
# If there's a perl test script (.plt) available, use it
%.t: ../%.plt
@$(RM) $@
@$(CP) $< $@
# Early versions of Test::Harness expect test programs in perl only.
# Generate a 1-line test program to run the real test binary
%.t: %$(EXE)
@$(RM) $@
@echo 'exec "$<";' >$@

View File

@@ -14,7 +14,7 @@
#include "epicsAssert.h"
#include "bucketLib.h"
main()
int main()
{
unsigned id1;
unsigned id2;

View File

@@ -10,50 +10,60 @@
// epicsAlgorithmTest.cpp
// Authors: Jeff Hill & Andrew Johnson
#include <assert.h>
#include <stdio.h>
#include "epicsUnitTest.h"
#include "epicsAlgorithm.h"
#if defined(vxWorks) || defined(__rtems__)
#define MAIN epicsAlgorithm
extern "C" int MAIN(int /*argc*/, char* /*argv[]*/);
#define MAIN(prog) extern "C" int prog
#else
#define MAIN main
#define MAIN(prog) int main
#endif
int MAIN(int /*argc*/, char* /*argv[]*/)
MAIN(epicsAlgorithm) (int /*argc*/, char* /*argv[]*/)
{
testPlan(22);
float f0 = 0.0;
float f1 = 3.3f;
float f2 = 3.4f;
float f3;
float Inf = 1.0 / f0;
float NaN = 0.0 / f0;
f3 = epicsMin(f1,f2);
assert(f3==f1);
testOk(epicsMin(f1, f2) == f1, "epicsMin(f1, f2)");
testOk(epicsMin(f1, -Inf) == -Inf, "epicsMin(f1, -Inf)");
testOk(isnan(epicsMin(f1, NaN)), "epicsMin(f1, NaN)");
testOk(epicsMin(f1, Inf) == f1, "epicsMin(f1, Inf)");
f3 = epicsMax(f1,f2);
assert(f3==f2);
testOk(epicsMin(f2, f1) == f1, "epicsMin(f2, f1)");
testOk(epicsMin(-Inf, f1) == -Inf, "epicsMin(-Inf, f1)");
testOk(isnan(epicsMin(NaN, f1)), "epicsMin(NaN, f1)");
testOk(epicsMin(Inf, f1) == f1, "epicsMin(Inf, f1)");
testOk(epicsMax(f2, f1) == f2, "epicsMax(f2, f1)");
testOk(epicsMax(-Inf, f1) == f1, "epicsMax(-Inf, f1)");
testOk(isnan(epicsMax(NaN, f1)), "epicsMax(NaN, f1)");
testOk(epicsMax(Inf, f1) == Inf, "epicsMax(Inf, f1)");
testOk(epicsMax(f1, f2) == f2, "epicsMax(f1, f2)");
testOk(epicsMax(f1, -Inf) == f1, "epicsMax(f1, -Inf)");
testOk(isnan(epicsMax(f1, NaN)), "epicsMax(f1, NaN)");
testOk(epicsMax(f1, Inf) == Inf, "epicsMax(f1, Inf)");
epicsSwap(f1,f2);
assert(f1==3.4f);
assert(f2==3.3f);
testOk(f1==3.4f && f2==3.3f, "epicsSwap(f1, f2)");
int i1 = 3;
int i2 = 4;
int i3;
i3 = epicsMin(i1,i2);
assert(i3==i1);
testOk(epicsMin(i1,i2)==i1, "epicsMin(i1,i2)");
testOk(epicsMin(i2,i1)==i1, "epicsMin(i2,i1)");
i3 = epicsMax(i1,i2);
assert(i3==i2);
testOk(epicsMax(i1,i2)==i2, "epicsMax(i1,i2)");
testOk(epicsMax(i2,i1)==i2, "epicsMax(i2,i1)");
epicsSwap(i1,i2);
assert(i1==4);
assert(i2==3);
testOk(i1==4 && i2==3, "epicsSwap(i1,i2)");
puts("epicsMin, epicsMax and epicsSwap tested OK.");
return 0;
return testDone();
}

View File

@@ -9,7 +9,7 @@
\*************************************************************************/
//
// Verify that the local c++ exception mechanism maches the ANSI/ISO standard.
// Verify that the local c++ exception mechanism matches the ANSI/ISO standard.
// Author: Jeff Hill
//
@@ -21,9 +21,9 @@
#include <limits>
#endif
#include <assert.h>
#include <stdio.h>
#include "epicsUnitTest.h"
#include "epicsThread.h"
using namespace std;
@@ -60,24 +60,23 @@ private:
static void epicsExceptionTestPrivate ()
{
int excep = false;
try {
new char [unsuccessfulNewSize];
assert ( 0 );
testFail("new: didn't throw at all");
}
catch ( const bad_alloc & ) {
excep = true;
testPass("new");
}
catch ( ... ) {
assert ( 0 );
testFail("new: threw wrong type");
}
try {
char * p = new ( nothrow )
char [unsuccessfulNewSize];
assert ( p == 0);
testOk(p == 0, "new (nothrow)");
}
catch( ... ) {
assert ( 0 );
testFail("new (nothrow): threw");
}
}
@@ -101,13 +100,12 @@ void exThread::waitForCompletion ()
}
}
extern "C" void epicsExceptionTest ()
extern "C" int epicsExceptionTest ()
{
exThread athread;
testPlan(4);
epicsExceptionTestPrivate ();
exThread athread;
athread.waitForCompletion ();
printf ( "Test Complete.\n" );
return testDone();
}

View File

@@ -8,10 +8,9 @@
* in file LICENSE that is included with this distribution.
\*************************************************************************/
extern "C" void epicsExceptionTest ();
extern "C" int epicsExceptionTest ();
int main ()
{
epicsExceptionTest ();
return 0;
return epicsExceptionTest ();
}

View File

@@ -12,34 +12,56 @@
* Author Marty Kraimer
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "epicsUnitTest.h"
#include "epicsMath.h"
static char *truth[2] = {"false","true"};
int epicsMathTest ()
{
double a,b,c;
a=0.0; b=0.0; c=a/b;
printf("a %e b %e c %e isnan %s isinf %s\n",
a,b,c,truth[isnan(c) ? 1 : 0],truth[isinf(c) ? 1 : 0]);
a=1e300; b=1e-300; c=a/b;
printf("a %e b %e c %e isnan %s isinf %s\n",
a,b,c,truth[isnan(c) ? 1 : 0],truth[isinf(c) ? 1 : 0]);
a=-1e300; b=1e-300; c=a/b;
printf("a %e b %e c %e isnan %s isinf %s\n",
a,b,c,truth[isnan(c) ? 1 : 0],truth[isinf(c) ? 1 : 0]);
a=0.0; b=1.0; c=a/b;
printf("a %e b %e c %e isnan %s isinf %s\n",
a,b,c,truth[isnan(c) ? 1 : 0],truth[isinf(c) ? 1 : 0]);
a=1e300; b=1e300; c=a/b;
printf("a %e b %e c %e isnan %s isinf %s\n",
a,b,c,truth[isnan(c) ? 1 : 0],truth[isinf(c) ? 1 : 0]);
return(0);
testPlan(18);
a = 0.0;
b = 1.0;
c = a / b;
testOk(!isnan(c), "!isnan(0.0 / 1.0)");
testOk(!isinf(c), "!isinf(0.0 / 1.0)");
testOk(c == 0.0, "0.0 / 1.0 == 0.0");
a = 1.0;
b = 0.0;
c = a / b;
testOk(!isnan(c), "!isnan(1.0 / 0.0)");
testOk(isinf(c), "isinf(1.0 / 0.0)");
testOk(c == c, "1.0 / 0.0 == 1.0 / 0.0");
a = 0.0;
b = 0.0;
c = a / b;
testOk(isnan(c), "isnan(0.0 / 0.0)");
testOk(!isinf(c), "!isinf(0.0 / 0.0)");
testOk(c != c, "0.0 / 0.0 != 0.0 / 0.0");
a = 1e300;
b = 1e-300;
c = a / b;
testOk(!isnan(c), "!isnan(1e300 / 1e-300)");
testOk(isinf(c), "isinf(1e300 / 1e-300)");
testOk(c > 0.0, "1e300 / 1e-300 > 0.0");
a = -1e300;
b = 1e-300;
c = a / b;
testOk(!isnan(c), "!isnan(-1e300 / 1e-300)");
testOk(isinf(c), "isinf(-1e300 / 1e-300)");
testOk(c < 0.0, "-1e300 / 1e-300 < 0.0");
a = 1e300;
b = 1e300;
c = a / b;
testOk(!isnan(c), "!isnan(1e300 / 1e300)");
testOk(!isinf(c), "!isinf(1e300 / 1e300)");
testOk(c == 1.0, "1e300 / 1e300 == 1.0");
return testDone();
}

View File

@@ -22,83 +22,77 @@
#include <errno.h>
#include "epicsStdio.h"
#include "epicsStdioRedirect.h"
#include "epicsUnitTest.h"
static int xsnprintf(char *str, size_t size, const char *format, ...)
{
int nchar;
va_list pvar;
va_start(pvar,format);
nchar = epicsVsnprintf(str,size,format,pvar);
va_end (pvar);
return(nchar);
static void testEpicsSnprintf() {
const int ivalue = 1234;
const float fvalue = 1.23e4;
const char *svalue = "OneTwoThreeFour";
const char *format = "int %d float %8.2e string %s";
const char *result = "int 1234 float 1.23e+04 string OneTwoThreeFour";
char buffer[80];
int size, rtn;
int rlen = strlen(result)+1;
strcpy(buffer, "AAAA");
for (size = 0; size < strlen(result) + 5; ++size) {
rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue);
testOk1(rtn == rlen-1);
if (size) {
testOk(strncmp(buffer, result, size-1) == 0, buffer);
testOk(strlen(buffer) == (size < rlen ? size : rlen) -1, "length");
} else {
testOk(strcmp(buffer, "AAAA") == 0, "Buffer unmodified, size=0");
}
}
}
int epicsStdioTest (const char *report)
void testStdoutRedir (const char *report)
{
char buffer[20];
int rtn;
int value = 10;
int size = 10;
FILE *realStdout = stdout;
FILE *stream = 0;
memset(buffer,'*',sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0;
printf("at start buffer |%s|\n",buffer);
rtn = xsnprintf(buffer,size,"value is %d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
memset(buffer,'*',sizeof(buffer)-1);
rtn = xsnprintf(buffer,size,"value: %d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
memset(buffer,'*',sizeof(buffer)-1);
rtn = xsnprintf(buffer,size,"%d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
memset(buffer,'*',sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0;
printf("at start buffer |%s|\n",buffer);
rtn = epicsSnprintf(buffer,size,"value is %d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
memset(buffer,'*',sizeof(buffer)-1);
rtn = epicsSnprintf(buffer,size,"value: %d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
memset(buffer,'*',sizeof(buffer)-1);
rtn = epicsSnprintf(buffer,size,"%d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
printf("\nTest epicsSetThreadStdout/epicsGetStdout stdout %p epicsGetStdout %p\n",
stdout,epicsGetStdout());
testOk1(epicsGetStdout() == stdout);
if(report && strlen(report)>0) {
int fd;
int fd;
errno = 0;
fd = open(report, O_CREAT | O_WRONLY | O_TRUNC, 0644 );
if(fd<0) {
fprintf(stderr,"%s could not be created %s\n",
report,strerror(errno));
} else {
stream = fdopen(fd,"w");
if(!stream) {
fprintf(stderr,"%s could not be opened for output %s\n",
report,strerror(errno));
} else {
epicsSetThreadStdout(stream);
printf("After epicsSetThreadStdout stream %p epicsGetStdout %p\n",
stream,epicsGetStdout());
}
}
errno = 0;
fd = open(report, O_CREAT | O_WRONLY | O_TRUNC, 0644 );
if(fd<0) {
fprintf(stderr,"%s could not be created %s\n",
report,strerror(errno));
} else {
stream = fdopen(fd,"w");
if(!stream) {
fprintf(stderr,"%s could not be opened for output %s\n",
report,strerror(errno));
} else {
epicsSetThreadStdout(stream);
testOk1(stdout == stream);
}
}
}
printf("This is first line of sample report");
printf("\nThis is second and last line of sample report\n");
printf("# This is first line of sample report\n");
printf("# This is second and last line of sample report\n");
errno = 0;
if(stream) {
epicsSetThreadStdout(0);
if(fclose(stream)) {
fprintf(stderr,"fclose failed %s\n",strerror(errno));
}
epicsSetThreadStdout(0);
if(fclose(stream)) {
fprintf(stderr,"fclose failed %s\n",strerror(errno));
}
} else {
fflush(stdout);
fflush(stdout);
}
printf("at end stdout %p epicsGetStdout %p\n",stdout,epicsGetStdout());
return(0);
testOk1(epicsGetStdout() == realStdout);
testOk1(stdout == realStdout);
}
int epicsStdioTest (const char *report)
{
testPlan(0);
testEpicsSnprintf();
testStdoutRedir("report");
return testDone();
}

View File

@@ -7,46 +7,42 @@
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* epicsStdioTest.c
/* $Id$
*
* Author Marty Kraimer
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "epicsUnitTest.h"
#include "epicsString.h"
int epicsStringTest()
{
if(epicsStrnCaseCmp("","",0)!=0) printf("case 1 failed\n");
if(epicsStrnCaseCmp("","",1)!=0) printf("case 2 failed\n");
if(epicsStrnCaseCmp(" ","",1)!=-1) printf("case 3 failed\n");
if(epicsStrnCaseCmp(""," ",1)!=1) printf("case 4 failed\n");
if(epicsStrnCaseCmp("a","A",1)!=0) printf("case 5 failed\n");
if(epicsStrnCaseCmp("a","A",2)!=0) printf("case 6 failed\n");
if(epicsStrnCaseCmp("abcd","ABCD",2)!=0) printf("case 7 failed\n");
if(epicsStrnCaseCmp("abcd","ABCD",4)!=0) printf("case 8 failed\n");
if(epicsStrnCaseCmp("abcd","ABCD",1000)!=0) printf("case 9 failed\n");
if(epicsStrnCaseCmp("abcd","ABCDE",2)!=0) printf("case 10 failed\n");
if(epicsStrnCaseCmp("abcd","ABCDE",4)!=0) printf("case 11 failed\n");
if(epicsStrnCaseCmp("abcd","ABCDE",1000)!=1) printf("case 12 failed\n");
if(epicsStrnCaseCmp("abcde","ABCD",2)!=0) printf("case 13 failed\n");
if(epicsStrnCaseCmp("abcde","ABCD",4)!=0) printf("case 14 failed\n");
if(epicsStrnCaseCmp("abcde","ABCD",1000)!=-1) printf("case 15 failed\n");
testPlan(21);
testOk1(epicsStrnCaseCmp("","",0)==0);
testOk1(epicsStrnCaseCmp("","",1)==0);
testOk1(epicsStrnCaseCmp(" ","",1)<0);
testOk1(epicsStrnCaseCmp(""," ",1)>0);
testOk1(epicsStrnCaseCmp("a","A",1)==0);
testOk1(epicsStrnCaseCmp("a","A",2)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCD",2)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCD",4)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCD",1000)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCDE",2)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCDE",4)==0);
testOk1(epicsStrnCaseCmp("abcd","ABCDE",1000)>0);
testOk1(epicsStrnCaseCmp("abcde","ABCD",2)==0);
testOk1(epicsStrnCaseCmp("abcde","ABCD",4)==0);
testOk1(epicsStrnCaseCmp("abcde","ABCD",1000)<0);
if(epicsStrCaseCmp("","")!=0) printf("case 16 failed\n");
if(epicsStrCaseCmp("a","A")!=0) printf("case 17 failed\n");
if(epicsStrCaseCmp("abcd","ABCD")!=0) printf("case 18 failed\n");
if(epicsStrCaseCmp("abcd","ABCDE")==0) printf("case 19 failed\n");
if(epicsStrCaseCmp("abcde","ABCD")==0) printf("case 20 failed\n");
if(epicsStrCaseCmp("abcde","ABCDF")==0) printf("case 21 failed\n");
testOk1(epicsStrCaseCmp("","")==0);
testOk1(epicsStrCaseCmp("a","A")==0);
testOk1(epicsStrCaseCmp("abcd","ABCD")==0);
testOk1(epicsStrCaseCmp("abcd","ABCDE")!=0);
testOk1(epicsStrCaseCmp("abcde","ABCD")!=0);
testOk1(epicsStrCaseCmp("abcde","ABCDF")!=0);
printf("String comparison tests completed.\n");
return(0);
return testDone();
}

View File

@@ -14,40 +14,13 @@
#include <time.h>
#include <math.h>
#include <limits.h>
#include <cstring>
#include <string.h>
#include "epicsTime.h"
#include "epicsThread.h"
#include "errlog.h"
#include "epicsUnitTest.h"
extern "C" {
int epicsTimeTest (void);
}
void invalidFormatTest ()
{
epicsTime ts ( epicsTime::getCurrent () );
char bigBuf [512];
char buf [32];
memset ( bigBuf, '\a', sizeof ( bigBuf ) );
bigBuf [ sizeof ( bigBuf ) - 1 ] = '\0';
ts.strftime ( buf, sizeof ( buf ), bigBuf );
printf ("A huge strftime format produces this result \"%s\"\n", buf );
}
void badNanosecTest ()
{
static const char * pFormat = "%a %b %d %Y %H:%M:%S.%4f";
try {
const epicsTimeStamp ets = { 1, 1000000000 };
epicsTime ts ( ets );
char buf [32];
ts.strftime ( buf, sizeof ( buf ), pFormat );
printf ("A nano-sec overflow produces this result \"%s\"\n", buf );
}
catch ( ... ) {
}
}
struct l_fp { /* NTP time stamp */
epicsUInt32 l_ui; /* sec past NTP epoch */
@@ -60,44 +33,17 @@ static const unsigned mSecPerSec = 1000u;
static const unsigned uSecPerSec = 1000u * mSecPerSec;
static const unsigned nSecPerSec = 1000u * uSecPerSec;
void testStringConversion()
{
char buf[64];
epicsTime uninit;
const char * pFormat = "%a %b %d %Y %H:%M:%S.%f";
uninit.strftime ( buf, sizeof ( buf ), pFormat );
printf ("Uninitialized using \"%s\" %s\n", pFormat, buf );
epicsTime current = epicsTime::getCurrent();
pFormat = "%a %b %d %Y %H:%M:%S.%f";
current.strftime ( buf, sizeof ( buf ), pFormat );
printf ("using \"%s\" %s\n", pFormat, buf );
pFormat = "%a %b %d %Y %H:%M:%S.%4f";
current.strftime ( buf, sizeof ( buf ), pFormat );
printf ("using \"%s\" %s\n", pFormat, buf );
pFormat = "%a %b %d %Y %H:%M:%S.%05f";
current.strftime ( buf, sizeof ( buf ), pFormat );
printf ("using \"%s\" %s\n", pFormat, buf );
}
extern "C"
int epicsTimeTest (void)
{
unsigned errors, sum_errors=0, sum_errloops=0;
const epicsTime begin = epicsTime::getCurrent();
const unsigned wasteTime = 100000u;
const int nTimes = 100;
epicsTimeStamp stamp;
struct timespec ts;
struct tm tmAnsi;
local_tm_nano_sec ansiDate;
gm_tm_nano_sec ansiDateGMT;
unsigned long nanoSec;
const int nTimes = 10;
const double precisionEPICS = 1.0 / nSecPerSec;
testPlan(7 + nTimes * 18);
const epicsTime begin = epicsTime::getCurrent();
{
epicsTime tsi = epicsTime::getCurrent ();
l_fp ntp = tsi;
@@ -105,14 +51,63 @@ int epicsTimeTest (void)
const double diff = fabs ( tsf - tsi );
// the difference in the precision of the two time formats
static const double precisionNTP = 1.0 / ( 1.0 + 0xffffffff );
static const double precisionEPICS = 1.0 / nSecPerSec;
assert ( diff <= precisionEPICS + precisionNTP );
testOk1(diff <= precisionEPICS + precisionNTP);
}
invalidFormatTest ();
badNanosecTest ();
printf ("epicsTime Test (%3d loops)\n========================\n\n", nTimes);
{
static const char * pFormat = "%a %b %d %Y %H:%M:%S.%4f";
try {
const epicsTimeStamp badTS = {1, 1000000000};
epicsTime ts(badTS);
char buf [32];
ts.strftime(buf, sizeof(buf), pFormat);
testFail("nanosecond overflow throws");
testDiag("nanosecond overflow result is \"%s\"", buf);
}
catch ( ... ) {
testPass("nanosecond overflow throws");
}
}
{
char buf[64];
epicsTime et;
const char * pFormat = "%Y-%m-%d %H:%M:%S.%f";
et.strftime(buf, sizeof(buf), pFormat);
testOk(strcmp(buf, "<undefined>") == 0, "undefined strftime") ||
testDiag("undefined.strftime(\"%s\") = \"%s\"", pFormat, buf);
// This is Noon GMT, when all timezones have the same date
const epicsTimeStamp tTS = {12*60*60, 98765432};
et = tTS;
pFormat = "%Y-%m-%d %S.%09f"; // %H and %M change with timezone
et.strftime(buf, sizeof(buf), pFormat);
testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, pFormat) ||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
pFormat = "%S.%04f";
et.strftime(buf, sizeof(buf), pFormat);
testOk(strcmp(buf, "00.0988") == 0, pFormat) ||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
pFormat = "%S.%05f";
et.strftime(buf, sizeof(buf), pFormat);
testOk(strcmp(buf, "00.09877") == 0, pFormat) ||
testDiag("t.strftime(\"%s\") = \"%s\"", pFormat, buf);
}
{
char bigBuf [512];
char buf [32];
memset(bigBuf, '\a', sizeof(bigBuf ));
bigBuf[ sizeof(bigBuf) - 1] = '\0';
begin.strftime(buf, sizeof(buf), bigBuf);
testOk(strcmp(buf, "<invalid format>") == 0, "strftime(huge)") ||
testDiag("strftime(huge) = \"%s\"", buf);
}
testDiag("Running %d loops", nTimes);
for (int iTimes=0; iTimes < nTimes; ++iTimes) {
for (unsigned i=0; i<wasteTime; i++) {
@@ -120,135 +115,52 @@ int epicsTimeTest (void)
}
const epicsTime end = epicsTime::getCurrent();
const double diff = end - begin;
if (iTimes == 0) {
printf ("Time per call to epicsTime::getCurrent() "
"(%d calls) = %6.3f usec\n\n", wasteTime,
testDiag ("%d calls to epicsTime::getCurrent() "
"averaged %6.3f usec each", wasteTime,
diff*1e6/wasteTime);
stamp = begin;
ansiDate = begin;
ansiDateGMT = begin;
ts = begin;
printf ("The following should be your local time\ndisplayed using "
"four different internal representations:\n\n");
epicsTimeToTM (&tmAnsi, &nanoSec, &stamp);
printf ("epicsTimeStamp = %s %lu nSec \n", asctime(&tmAnsi), nanoSec);
printf ("local time zone struct tm = %s %f\n", asctime(&ansiDate.ansi_tm),
ansiDate.nSec/(double)nSecPerSec);
printf ("struct timespec = %s %f\n", asctime(&ansiDate.ansi_tm),
ts.tv_nsec/(double)nSecPerSec);
printf ("UTC struct tm = %s %f\n", asctime(&ansiDateGMT.ansi_tm),
ansiDateGMT.nSec/(double)nSecPerSec);
begin.show (100);
printf ("\n");
} else {
if (iTimes % 10 == 0)
printf (" ... now at loop %3d\n", iTimes);
}
}
epicsTime copy = end;
errors = 0;
testOk1(copy == end);
testOk1(copy <= end);
testOk1(copy >= end);
if (!(copy==end)) {
printf ("#%3d: Failed copy==end by %12.9f\n",
iTimes, fabs(copy-end));
errors += 1;
}
if (!(copy<=end)) {
printf ("#%3d: Failed copy<=end by %12.9f\n",
iTimes, (copy-end));
errors += 1;
}
if (!(copy>=end)) {
printf ("#%3d: Failed copy>=end by %12.9f\n",
iTimes, (end-copy));
errors += 1;
}
if (!(end>begin)) {
printf ("#%3d: Failed end>begin by %12.9f\n",
iTimes, (begin-end));
errors += 1;
}
if (!(end>=begin)) {
printf ("#%3d: Failed end>=begin by %12.9f\n",
iTimes, (begin-end));
errors += 1;
}
if (!(begin<end)) {
printf ("#%3d: Failed begin<end by %12.9f\n",
iTimes, (begin-end));
errors += 1;
}
if (!(begin<=end)) {
printf ("#%3d: Failed begin<=end by %12.9f\n",
iTimes, (begin-end));
errors += 1;
}
if (!(begin!=end)) {
printf ("#%3d: Failed begin!=end\n",iTimes);
errors += 1;
}
const double diff2 = end - begin;
if (!(diff2==diff)) {
printf ("#%3d: Failed end-begin==diff by %g\n",
iTimes, fabs(diff2-diff));
errors += 1;
}
testOk1(end > begin);
testOk1(end >= begin);
testOk1(begin != end);
testOk1(begin < end);
testOk1(begin <= end);
testOk1(end - end == 0);
testOk(fabs((end - begin) - diff) < precisionEPICS * 0.01,
"end - begin ~= diff");
testOk1(begin + 0 == begin);
testOk1(begin + diff == end);
testOk1(end - 0 == end);
testOk1(end - diff == begin);
epicsTime end2 = begin;
end2 += diff;
if (!(end2==end)) {
printf ("#%3d: Failed (begin+=diff)==end by %12.9f\n",
iTimes, fabs(begin-end));
errors += 1;
}
end2 += diff;
testOk(end2 == end, "(begin += diff) == end");
end2 = end;
end2 -= diff;
if (!(end2+diff==end)) {
printf ("#%3d: Failed begin+diff==end by %12.9f\n",
iTimes, fabs(begin+diff-end));
errors += 1;
}
testOk(end2 == begin, "(end -= diff) == begin");
//
// test struct tm conversions
//
ansiDate = begin;
epicsTime beginANSI = ansiDate;
if (!(beginANSI+diff==end)) {
printf ("#%3d: Failed begin+diff==end "
"after tm conversions by %12.9f\n",
iTimes, fabs(begin+diff-end));
errors += 1;
}
// test struct tm round-trip conversion
local_tm_nano_sec ansiDate = begin;
epicsTime beginANSI = ansiDate;
testOk1(beginANSI + diff == end);
//
// test struct timespec conversion
//
ts = begin;
// test struct timespec round-trip conversion
struct timespec ts = begin;
epicsTime beginTS = ts;
if (!(beginTS+diff==end)) {
printf ("#%3d: Failed begin+diff==end "
"after timespec conversions by %12.9f\n",
iTimes, fabs(begin+diff-end));
errors += 1;
}
if (errors) {
printf ("#%3d: begin ", iTimes); begin.show(0);
printf ("#%3d: end ", iTimes); end.show(0);
printf ("#%3d: diff %12.9f\n\n", iTimes, diff);
sum_errors += errors;
sum_errloops += 1;
}
testOk1(beginTS + diff == end);
}
printf ("epicsTime test complete. Summary: %d errors found "
"in %d out of %d loops.\n",
sum_errors, sum_errloops, nTimes);
return (sum_errors?1:0);
return testDone();
}

View File

@@ -19,93 +19,87 @@
#include "macLib.h"
#include "envDefs.h"
#include "errlog.h"
#include "epicsUnitTest.h"
int
check(const char *str, const char *expect)
void check(const char *str, const char *expect)
{
char *got = macEnvExpand(str);
int bad = 0;
static int count = 0;
int pass = -1;
if (expect && !got) {
printf("\t#Got NULL, expected \"%s\".\n", expect);
bad = 1;
testDiag("Got NULL, expected \"%s\".\n", expect);
pass = 0;
}
else if (!expect && got) {
printf("\t#Got \"%s\", expected NULL.\n", got);
bad = 1;
testDiag("Got \"%s\", expected NULL.\n", got);
pass = 0;
}
else if (expect && got && strcmp(got, expect)) {
printf("\t#Got \"%s\", expected \"%s\".\n", got, expect);
bad = 1;
testDiag("Got \"%s\", expected \"%s\".\n", got, expect);
pass = 0;
}
/* This output format follows the perl standard: */
printf("%sok %d - \"%s\".\n", (bad ? "not " : ""), ++count, str);
return bad;
testOk(pass, str);
}
int macEnvExpandTest(void)
{
int bad = 0;
int warn = 0;
testPlan(30);
/* Announce the number of calls to check() present in the code below: */
printf("1..%d\n", 30);
check("FOO", "FOO");
bad |= check ("FOO", "FOO");
bad |= check ("${FOO}", NULL); warn++;
bad |= check ("${FOO=}", "");
bad |= check ("x${FOO=}y", "xy");
bad |= check ("${FOO=BAR}", "BAR");
bad |= check ("x${FOO=BAR}y", "xBARy");
check("${FOO}", NULL); warn++;
check("${FOO=}", "");
check("x${FOO=}y", "xy");
check("${FOO=BAR}", "BAR");
check("x${FOO=BAR}y", "xBARy");
epicsEnvSet("FOO","BLETCH");
bad |= check ("${FOO}", "BLETCH");
bad |= check ("x${FOO}y", "xBLETCHy");
bad |= check ("x${FOO}y${FOO}z", "xBLETCHyBLETCHz");
bad |= check ("${FOO=BAR}", "BLETCH");
bad |= check ("x${FOO=BAR}y", "xBLETCHy");
bad |= check ("${FOO=${BAZ}}", "BLETCH");
bad |= check ("x${FOO=${BAZ}}y", "xBLETCHy");
bad |= check ("${BAR=${FOO}}", "BLETCH");
bad |= check ("x${BAR=${FOO}}y", "xBLETCHy");
bad |= check ("w${BAR=x${FOO}y}z", "wxBLETCHyz");
check("${FOO}", "BLETCH");
check("x${FOO}y", "xBLETCHy");
check("x${FOO}y${FOO}z", "xBLETCHyBLETCHz");
check("${FOO=BAR}", "BLETCH");
check("x${FOO=BAR}y", "xBLETCHy");
check("${FOO=${BAZ}}", "BLETCH");
check("x${FOO=${BAZ}}y", "xBLETCHy");
check("${BAR=${FOO}}", "BLETCH");
check("x${BAR=${FOO}}y", "xBLETCHy");
check("w${BAR=x${FOO}y}z", "wxBLETCHyz");
epicsEnvSet("BAR","GLEEP");
bad |= check ("${FOO}/${BAR}", "BLETCH/GLEEP");
bad |= check ("x${FOO}/${BAR}y", "xBLETCH/GLEEPy");
bad |= check ("${BAR=${FOO}}", "GLEEP");
check("${FOO}/${BAR}", "BLETCH/GLEEP");
check("x${FOO}/${BAR}y", "xBLETCH/GLEEPy");
check("${BAR=${FOO}}", "GLEEP");
epicsEnvSet("BLETCH","BAR");
bad |= check ("${${FOO}}", "BAR");
bad |= check ("x${${FOO}}y", "xBARy");
bad |= check ("${${FOO}=GRIBBLE}", "BAR");
bad |= check ("x${${FOO}=GRIBBLE}y", "xBARy");
check("${${FOO}}", "BAR");
check("x${${FOO}}y", "xBARy");
check("${${FOO}=GRIBBLE}", "BAR");
check("x${${FOO}=GRIBBLE}y", "xBARy");
epicsEnvSet("BLETCH","${BAR}");
bad |= check ("${${FOO}}", "GLEEP");
check("${${FOO}}", "GLEEP");
epicsEnvSet("FOO","${BAR}");
bad |= check ("${FOO}","GLEEP");
check("${FOO}","GLEEP");
epicsEnvSet("BAR","${BAZ}");
bad |= check ("${FOO}", NULL); warn++;
check("${FOO}", NULL); warn++;
epicsEnvSet("BAR","${BAZ=GRIBBLE}");
bad |= check ("${FOO}", "GRIBBLE");
check("${FOO}", "GRIBBLE");
epicsEnvSet("BAR","${STR1}");
epicsEnvSet("STR1","VAL1");
epicsEnvSet("STR2","VAL2");
bad |= check ("${FOO}", "VAL1");
check("${FOO}", "VAL1");
epicsEnvSet("BAR","${STR2}");
bad |= check ("${FOO}", "VAL2");
check("${FOO}", "VAL2");
epicsEnvSet("BAR","${FOO}");
bad |= check ("${FOO}", NULL); warn++;
check("${FOO}", NULL); warn++;
printf("# Expect %d warning messages here:\n", warn);
testDiag("Expect %d warning messages here:\n", warn);
errlogFlush();
return bad;
return testDone();
}