This is Unofficial EPICS BASE Doxygen Site
epicsUnitTest.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "epicsThread.h"
#include "epicsMutex.h"
#include "epicsUnitTest.h"
#include "epicsExit.h"
#include "epicsTime.h"
#include "ellLib.h"
#include "errlog.h"
#include "cantProceed.h"
#include "epicsStackTrace.h"
+ Include dependency graph for epicsUnitTest.c:

Go to the source code of this file.

Classes

struct  testFailure
 

Functions

void testPlan (int plan)
 Declare the test plan, required. More...
 
int testOkV (int pass, const char *fmt, va_list pvar)
 Test result with var-args description. More...
 
int testOk (int pass, const char *fmt,...)
 
void testPass (const char *fmt,...)
 
void testFail (const char *fmt,...)
 
void testSkip (int skip, const char *why)
 Place-holders for tests that can't be run. More...
 
void testTodoBegin (const char *why)
 Mark the start of a group of tests that are expected to fail. More...
 
void testTodoEnd (void)
 Mark the end of a failing test group. More...
 
int testDiag (const char *fmt,...)
 
void testAbort (const char *fmt,...)
 
int testDone (void)
 Mark the end of testing. More...
 
int testImpreciseTiming (void)
 Return non-zero in shared/oversubscribed testing envrionments. More...
 
void testHarnessExit (void *dummy)
 
void testHarness (void)
 Initialize test harness. More...
 
void runTestFunc (const char *name, TESTFUNC func)
 

Variables

epicsTimeStamp started
 
ELLLIST faults
 
const char * testing = NULL
 

Function Documentation

void runTestFunc ( const char *  name,
TESTFUNC  func 
)

Definition at line 310 of file epicsUnitTest.c.

310  {
311  printf("\n***** %s *****\n", name);
312  testing = name;
313  func(); /* May not return */
314  epicsThreadSleep(1.0);
315 }
#define printf
Definition: epicsStdio.h:41
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
const char * testing
Definition: epicsUnitTest.c:58
void testAbort ( const char *  fmt,
  ... 
)

Definition at line 194 of file epicsUnitTest.c.

194  {
195  va_list pvar;
196  va_start(pvar, fmt);
197  printf("Bail out! ");
198  vprintf(fmt, pvar);
199  putchar('\n');
200  fflush(stdout);
201  va_end(pvar);
202  abort();
203 }
#define printf
Definition: epicsStdio.h:41
#define putchar
Definition: epicsStdio.h:51
#define stdout
Definition: epicsStdio.h:30
int testDiag ( const char *  fmt,
  ... 
)

Definition at line 181 of file epicsUnitTest.c.

181  {
182  va_list pvar;
183  va_start(pvar, fmt);
184  epicsMutexMustLock(testLock);
185  printf("# ");
186  vprintf(fmt, pvar);
187  putchar('\n');
188  fflush(stdout);
189  epicsMutexUnlock(testLock);
190  va_end(pvar);
191  return 0;
192 }
#define printf
Definition: epicsStdio.h:41
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define putchar
Definition: epicsStdio.h:51
#define stdout
Definition: epicsStdio.h:30
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
int testDone ( void  )

Mark the end of testing.

Definition at line 209 of file epicsUnitTest.c.

209  {
210  int status = 0;
211 
212  epicsMutexMustLock(testLock);
213  if (perlHarness) {
214  if (!planned) printf("1..%d\n", tested);
215  } else {
216  if (planned && tested > planned) {
217  printf("\nRan %d tests but only planned for %d!\n", tested, planned);
218  status = 2;
219  } else if (planned && tested < planned) {
220  printf("\nPlanned %d tests but only ran %d\n", planned, tested);
221  status = 2;
222  }
223  printf("\n Results\n =======\n Tests: %-3d\n", tested);
224  if (tested) {
225  testResult("Passed", passed);
226  if (bonus) testResult("Todo Passes", bonus);
227  if (failed) {
228  testResult("Failed", failed);
229  status = 1;
230  }
231  if (skipped) testResult("Skipped", skipped);
232  }
233  }
234  if (Harness) {
235  if (failed) {
236  testFailure *fault = callocMustSucceed(1, sizeof(testFailure),
237  "testDone calloc");
238  fault->name = testing;
239  fault->tests = tested;
240  fault->failures = failed;
241  fault->skips = skipped;
242  ellAdd(&faults, &fault->node);
243  }
244  Programs++;
245  Tests += tested;
246  }
247  epicsMutexUnlock(testLock);
248  return (status);
249 }
pvd::Status status
#define printf
Definition: epicsStdio.h:41
const char * name
Definition: epicsUnitTest.c:36
ELLLIST faults
Definition: epicsUnitTest.c:57
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
Definition: cantProceed.c:22
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
ELLNODE node
Definition: epicsUnitTest.c:35
const char * testing
Definition: epicsUnitTest.c:58
void testFail ( const char *  fmt,
  ... 
)

Definition at line 152 of file epicsUnitTest.c.

152  {
153  va_list pvar;
154  va_start(pvar, fmt);
155  testOkV(0, fmt, pvar);
156  va_end(pvar);
157 }
int testOkV(int pass, const char *fmt, va_list pvar)
Test result with var-args description.
void testHarness ( void  )

Initialize test harness.

Definition at line 300 of file epicsUnitTest.c.

300  {
301  epicsThreadOnce(&onceFlag, testOnce, NULL);
303  Harness = 1;
304  Programs = 0;
305  Tests = 0;
306  ellInit(&faults);
308 }
void testHarnessExit(void *dummy)
#define NULL
Definition: catime.c:38
ELLLIST faults
Definition: epicsUnitTest.c:57
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...
Definition: epicsExit.h:70
epicsTimeStamp started
Definition: epicsUnitTest.c:52
void testHarnessExit ( void *  dummy)

Definition at line 265 of file epicsUnitTest.c.

265  {
266  epicsTimeStamp ended;
267  int Faulty;
268 
269  if (!Harness) return;
270 
271  epicsTimeGetCurrent(&ended);
272 
273  printf("\n\n EPICS Test Harness Results"
274  "\n ==========================\n\n");
275 
276  Faulty = ellCount(&faults);
277  if (!Faulty)
278  printf("All tests successful.\n");
279  else {
280  int Failures = 0;
281  testFailure *f;
282 
283  printf("Failing Program Tests Faults\n"
284  "---------------------------------------\n");
285  while ((f = (testFailure *)ellGet(&faults))) {
286  Failures += f->failures;
287  printf("%-25s %5d %5d\n", f->name, f->tests, f->failures);
288  if (f->skips)
289  printf("%d subtests skipped\n", f->skips);
290  free(f);
291  }
292  printf("\nFailed %d/%d test programs. %d/%d subtests failed.\n",
293  Faulty, Programs, Failures, Tests);
294  }
295 
296  printf("Programs=%d, Tests=%d, %.0f wallclock secs\n\n",
297  Programs, Tests, epicsTimeDiffInSeconds(&ended, &started));
298 }
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
#define printf
Definition: epicsStdio.h:41
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
Definition: ellLib.c:147
const char * name
Definition: epicsUnitTest.c:36
ELLLIST faults
Definition: epicsUnitTest.c:57
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
EPICS time stamp, for use from C code.
Definition: epicsTime.h:33
LIBCOM_API double epicsStdCall epicsTimeDiffInSeconds(const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight)
Time difference between left and right in seconds.
Definition: epicsTime.cpp:1048
epicsTimeStamp started
Definition: epicsUnitTest.c:52
int testImpreciseTiming ( void  )

Return non-zero in shared/oversubscribed testing envrionments.

May be used to testSkip(), or select longer timeouts, for some cases when the test process may be preempted for arbitrarily long times. This is common in shared CI environments.

The environment variable $EPICS_TEST_IMPRECISE_TIMING=YES should be set in by such testing environments.

Definition at line 253 of file epicsUnitTest.c.

254 {
255  if(impreciseTiming==0) {
256  const char* env = getenv("EPICS_TEST_IMPRECISE_TIMING");
257 
258  impreciseTiming = (env && strcmp(env, "YES")==0) ? 1 : -1;
259  }
260  return impreciseTiming>0;
261 }
int testOk ( int  pass,
const char *  fmt,
  ... 
)

Definition at line 137 of file epicsUnitTest.c.

137  {
138  va_list pvar;
139  va_start(pvar, fmt);
140  testOkV(pass, fmt, pvar);
141  va_end(pvar);
142  return pass;
143 }
int testOkV(int pass, const char *fmt, va_list pvar)
Test result with var-args description.
int testOkV ( int  pass,
const char *  fmt,
va_list  pvar 
)

Test result with var-args description.

Parameters
passTrue/False value indicating result.
fmtA printf-style format string describing the test.
pvarA var-args pointer to any parameters for the format string.
Returns
The value of pass.

Definition at line 112 of file epicsUnitTest.c.

112  {
113  const char *result = "not ok";
114  epicsMutexMustLock(testLock);
115  tested++;
116  if (pass) {
117  result += 4; /* skip "not " */
118  passed++;
119  if (todo)
120  bonus++;
121  } else {
122  if (todo)
123  passed++;
124  else
125  failed++;
126  }
127  printf("%s %2d - ", result, tested);
128  vprintf(fmt, pvar);
129  if (todo)
130  printf(" # TODO %s", todo);
131  putchar('\n');
132  fflush(stdout);
133  epicsMutexUnlock(testLock);
134  return pass;
135 }
pvac::PutEvent result
Definition: clientSync.cpp:117
#define printf
Definition: epicsStdio.h:41
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define putchar
Definition: epicsStdio.h:51
#define stdout
Definition: epicsStdio.h:30
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void testPass ( const char *  fmt,
  ... 
)

Definition at line 145 of file epicsUnitTest.c.

145  {
146  va_list pvar;
147  va_start(pvar, fmt);
148  testOkV(1, fmt, pvar);
149  va_end(pvar);
150 }
int testOkV(int pass, const char *fmt, va_list pvar)
Test result with var-args description.
void testPlan ( int  tests)

Declare the test plan, required.

Parameters
testsNumber of tests to be run. May be zero if not known but the test harness then can't tell if the program dies prematurely.

Definition at line 102 of file epicsUnitTest.c.

102  {
103  epicsThreadOnce(&onceFlag, testOnce, NULL);
104  epicsMutexMustLock(testLock);
105  planned = plan;
106  tested = passed = failed = skipped = bonus = 0;
107  todo = NULL;
108  if (plan) printf("1..%d\n", plan);
109  epicsMutexUnlock(testLock);
110 }
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void testSkip ( int  skip,
const char *  why 
)

Place-holders for tests that can't be run.

Parameters
skipHow many tests are being skipped.
whyReason for skipping these tests.

Definition at line 159 of file epicsUnitTest.c.

159  {
160  epicsMutexMustLock(testLock);
161  while (skip-- > 0) {
162  tested++;
163  passed++;
164  skipped++;
165  printf("ok %2d # SKIP %s\n", tested, why);
166  }
167  fflush(stdout);
168  epicsMutexUnlock(testLock);
169 }
#define printf
Definition: epicsStdio.h:41
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define stdout
Definition: epicsStdio.h:30
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void testTodoBegin ( const char *  why)

Mark the start of a group of tests that are expected to fail.

Parameters
whyReason for expected failures.

Definition at line 171 of file epicsUnitTest.c.

171  {
172  epicsMutexMustLock(testLock);
173  todo = why;
174  epicsMutexUnlock(testLock);
175 }
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void testTodoEnd ( void  )

Mark the end of a failing test group.

Definition at line 177 of file epicsUnitTest.c.

177  {
179 }
void testTodoBegin(const char *why)
Mark the start of a group of tests that are expected to fail.
#define NULL
Definition: catime.c:38

Variable Documentation

ELLLIST faults

Definition at line 57 of file epicsUnitTest.c.

epicsTimeStamp started

Definition at line 52 of file epicsUnitTest.c.

const char* testing = NULL

Definition at line 58 of file epicsUnitTest.c.