test.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /***********************************************************************
  2. **
  3. ** Filename : test.c
  4. ** Project : Unit Test
  5. ** Subsystem :
  6. ** Module : Basic routines for performing a Unit Test
  7. ** Document :
  8. **
  9. *************************************************************************
  10. **
  11. ** Brief Description
  12. ** =================
  13. **
  14. ** Functions to provide a nice, consistent Unit Test infrastructure.
  15. **
  16. **
  17. *************************************************************************
  18. **
  19. ** Change History
  20. ** --------------
  21. **
  22. ** 20-Jun-2005 Graeme McKerrell Populated lub_test_stop_here() t ensure it is reached when a
  23. ** optimising compiler is used.
  24. ** 7-Dec-2004 Graeme McKerrell Updated to use the "lub_test_" prefix
  25. ** rather than "unittest_"
  26. ** 4 Mar 2004 Graeme McKerrell Ported for use in Garibaldi
  27. ** 4 Oct 2002 Graeme McKerrell updated to use central interface
  28. ** definition
  29. ** 18-Mar-2002 Graeme McKerrell Added unitest_stop_here() support
  30. ** 16-Mar-2002 Graeme McKerrell LINTed...
  31. ** 14 Nov 2000 Brett B. Bonner created
  32. **
  33. *************************************************************************
  34. **
  35. ** Copyright (C) 3Com Corporation. All Rights Reserved.
  36. **
  37. \************************************************************************/
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include <stdarg.h>
  41. #include <stdlib.h>
  42. /*lint -esym(534,vsprintf) */
  43. /*lint -esym(632,va_list,__va_list) */
  44. /*lint -esym(633,va_list,__gnuc_va_list) */
  45. #include "lub/test.h"
  46. /* Where to direct output (bitmasks) */
  47. #define LUB_TEST_LOGTOFILE 0x1
  48. #define LUB_TEST_LOGTOSTDOUT 0x2
  49. /* Termination Mode */
  50. typedef enum {
  51. ContinueOnFail,
  52. StopOnFail
  53. } TerminationMode;
  54. /* local variables */
  55. static char unitTestName[80];
  56. static char seqDescr[80];
  57. static FILE *logp=NULL;
  58. static lub_test_verbosity_t verbosity = LUB_TEST_NORMAL;
  59. static int outputTo;
  60. static lub_test_status_t unitTestStatus=LUB_TEST_PASS;
  61. static int seqNum=0;
  62. static int testNum=0;
  63. static int failureCount=0;
  64. static int testCount=0;
  65. static TerminationMode termMode=ContinueOnFail;
  66. /* local functions */
  67. static void testLogNoIndent(lub_test_verbosity_t level, const char *format, ...);
  68. static void printUsage(void);
  69. /* definitions */
  70. #define LOGGING_TO_FILE ((outputTo & LUB_TEST_LOGTOFILE) != 0)
  71. #define LOGGING_TO_STDOUT ((outputTo & LUB_TEST_LOGTOSTDOUT) != 0)
  72. /*
  73. * This is provided as a debug aid.
  74. */
  75. void
  76. lub_test_stop_here(void)
  77. {
  78. /* If any test fails, the unit test fails */
  79. unitTestStatus = LUB_TEST_FAIL;
  80. failureCount++;
  81. if (termMode == StopOnFail) {
  82. lub_test_end();
  83. exit(1);
  84. }
  85. }
  86. static lub_test_status_t
  87. checkStatus(lub_test_status_t value)
  88. {
  89. /* Test number gets incremented automatically... */
  90. testNum++;
  91. testCount++; /* update total number of tests performed */
  92. if(LUB_TEST_FAIL == value)
  93. {
  94. lub_test_stop_here();
  95. }
  96. return value;
  97. }
  98. /*******************************************************
  99. * unit-test-level functions
  100. ********************************************************/
  101. /* NAME: unitTestLog
  102. PURPOSE: Log output to file and/or stdout, verbosity-filtered
  103. ARGS: level - priority of this message.
  104. Will be logged only if priority equals or exceeds
  105. the current lub_test_verbosity_t level.
  106. format, args - printf-style format and parameters
  107. RETURN: none
  108. */
  109. static void
  110. unitTestLog(lub_test_verbosity_t level, const char *format, ...)
  111. {
  112. va_list args;
  113. char string[320]; /* ought to be big enough; that's 4 lines */
  114. /* Turn format,args into a string */
  115. va_start(args, format);
  116. vsprintf(string, format, args);
  117. va_end(args);
  118. /* output to selected destination if lub_test_verbosity_t equals or exceeds
  119. current setting. */
  120. if (level <= verbosity)
  121. {
  122. if (LOGGING_TO_FILE)
  123. {
  124. if (NULL != logp)
  125. {
  126. fprintf(logp, "%s\n", string);
  127. }
  128. else
  129. {
  130. fprintf(stderr, "ERROR: Trying to log to file, but no logfile is open!\n");
  131. }
  132. }
  133. if (LOGGING_TO_STDOUT)
  134. {
  135. fprintf(stdout, "%s\n", string);
  136. }
  137. }
  138. }
  139. /* NAME: TestStartLog
  140. PURPOSE: Sets up logging destination(s) and opens logfile.
  141. ARGS: whereToLog - where output gets directed to
  142. Bitmask of lub_test_LOGTOFILE, lub_test_LOGTOSTDOUT
  143. logfile - file name to open.
  144. Use NULL if not logging to file.
  145. RETURN: BOOL_FALSE == failure
  146. BOOL_TRUE == success
  147. */
  148. static int TestStartLog(int whereToLog, const char *logFile)
  149. {
  150. bool_t status = BOOL_TRUE;
  151. /* Where are we logging? */
  152. outputTo = whereToLog;
  153. /* open log file */
  154. if (LOGGING_TO_FILE && (strlen(logFile) < 1))
  155. {
  156. status = BOOL_FALSE;
  157. fprintf(stderr, "ERROR: No logfile name specified.\n");
  158. }
  159. if (LOGGING_TO_FILE && status)
  160. {
  161. if ( (logp = fopen(logFile, "w")) == NULL )
  162. {
  163. status = BOOL_FALSE;
  164. fprintf(stderr,
  165. "ERROR: could not open log file '%s'.\n",
  166. logFile);
  167. }
  168. }
  169. return status;
  170. }
  171. /* NAME: lub_test_begin
  172. PURPOSE: Starts unit test.
  173. ARGS: format,args - Specification of unit test name
  174. RETURN: none
  175. */
  176. void
  177. lub_test_begin(const char *name, ...)
  178. {
  179. va_list args;
  180. /* Process varargs list into unit test name string */
  181. va_start(args, name);
  182. vsprintf(unitTestName, name, args);
  183. va_end(args);
  184. unitTestLog(LUB_TEST_NORMAL, "BEGIN: Testing '%s'.", unitTestName);
  185. /* reset counters */
  186. seqNum=testNum=testCount=failureCount=0;
  187. }
  188. /* NAME: lub_test_get_status
  189. PURPOSE: Reports current unit test status
  190. ARGS: none
  191. RETURN: Status code - TESTPASS/TESTFAIL
  192. */
  193. lub_test_status_t
  194. lub_test_get_status(void)
  195. {
  196. return unitTestStatus;
  197. }
  198. /* NAME: lub_test_failure_count
  199. PURPOSE: Reports current number of test failures
  200. ARGS: none
  201. RETURN: Count of failures
  202. */
  203. int
  204. lub_test_failure_count(void)
  205. {
  206. return failureCount;
  207. }
  208. /* NAME: lub_test_end
  209. PURPOSE: Ends test. Closes log file.
  210. ARGS: none
  211. RETURN: none
  212. */
  213. void
  214. lub_test_end(void)
  215. {
  216. char result[40];
  217. if (unitTestStatus == LUB_TEST_PASS)
  218. {
  219. sprintf(result, "PASSED (%d tests)",testCount);
  220. }
  221. else
  222. {
  223. if (failureCount == 1)
  224. {
  225. sprintf(result, "FAILED (%d failure, %d tests)",
  226. failureCount, testCount);
  227. }
  228. else
  229. {
  230. sprintf(result, "FAILED (%d failures, %d tests)",
  231. failureCount, testCount);
  232. }
  233. }
  234. if ((termMode == ContinueOnFail) ||
  235. (unitTestStatus == LUB_TEST_PASS))
  236. {
  237. /* ran to end - either due to continue-on-fail, or because
  238. everything passed */
  239. unitTestLog(LUB_TEST_TERSE, "END: Test '%s' %s.\n",unitTestName, result);
  240. }
  241. else
  242. {
  243. /* stopped on first failure */
  244. unitTestLog(LUB_TEST_TERSE, "END: Test '%s': STOPPED AT FIRST FAILURE.\n",unitTestName);
  245. }
  246. if (LOGGING_TO_FILE)
  247. {
  248. fclose(logp);
  249. }
  250. }
  251. /* NAME: printUsage
  252. PURPOSE: Prints usage message
  253. ARGS: none
  254. RETURN: none
  255. */
  256. static void
  257. printUsage(void)
  258. {
  259. printf("Usage:\n");
  260. printf("-terse, -normal, -verbose : set lub_test_verbosity_t level (default: normal)\n");
  261. printf("-stoponfail, -continueonfail : set behavior upon failure (default: continue)\n");
  262. printf("-logfile [FILENAME] : log to FILENAME (default: 'test.log')\n");
  263. printf("-nologfile : disable logging to file \n");
  264. printf("-stdout, -nostdout : enable/disable logging to STDOUT\n");
  265. printf("-usage, -help : print these options and exit\n");
  266. printf("\nAll arguments are optional. Defaults are equivalent to: \n");
  267. printf(" -normal -continueonfail -logfile test.log -stdout\n");
  268. }
  269. /* NAME: lub_test_parse_command_line
  270. PURPOSE: Parses command-line arguments & sets unit test options.
  271. ARGS: argc, argv - as passed to main()
  272. RETURN: none (will exit if there is an error)
  273. */
  274. void
  275. lub_test_parse_command_line(int argc, const char * const *argv)
  276. {
  277. bool_t status=BOOL_TRUE;
  278. int logDest=0;
  279. static char defaultFile[] = "test.log";
  280. char *logFile;
  281. bool_t logFileAllocatedFromHeap=BOOL_FALSE;
  282. /* variables used to detect conflicting options */
  283. int verbset=0;
  284. int failset=0;
  285. int logfset=0;
  286. int stdset=0;
  287. /* Set logFile to defaultFile so there is always a valid filename.
  288. Also set logging destination to both STDOUT and FILE.
  289. These will be changed later if user specifies something else. */
  290. logFile = defaultFile;
  291. logDest = (LUB_TEST_LOGTOFILE | LUB_TEST_LOGTOSTDOUT);
  292. /* Loop through the command line arguments. */
  293. while (--argc > 0)
  294. {
  295. /* Usage/Help */
  296. if ((strstr(argv[argc], "-usage") != NULL) ||
  297. (strstr(argv[argc], "-help") != NULL))
  298. {
  299. printUsage();
  300. exit (0);
  301. }
  302. /* lub_test_verbosity_t Levels */
  303. else if (strstr(argv[argc], "-terse") != NULL)
  304. {
  305. verbosity = LUB_TEST_TERSE; verbset++;
  306. }
  307. else if (strstr(argv[argc], "-normal") != NULL)
  308. {
  309. verbosity = LUB_TEST_NORMAL; verbset++;
  310. }
  311. else if (strstr(argv[argc], "-verbose") != NULL)
  312. {
  313. verbosity = LUB_TEST_VERBOSE; verbset++;
  314. }
  315. /* Failure behavior */
  316. else if (strstr(argv[argc], "-stoponfail") != NULL)
  317. {
  318. termMode = StopOnFail; failset++;
  319. }
  320. else if (strstr(argv[argc], "-continueonfail") != NULL)
  321. {
  322. termMode = ContinueOnFail; failset++;
  323. }
  324. /* Log file options */
  325. else if (strstr(argv[argc], "-logfile") != NULL)
  326. {
  327. logDest |= LUB_TEST_LOGTOFILE;
  328. /* Was a log file name specified?
  329. We assume it's a file name if it doesn't start with '-' */
  330. if (strstr(argv[argc+1], "-") != argv[argc+1])
  331. {
  332. /* Yes, got a filename */
  333. logFile = (char *)malloc(strlen(argv[argc+1])+1);
  334. if (NULL == logFile)
  335. {
  336. status = BOOL_FALSE;
  337. fprintf(stderr, "unitTestParseCL: ERROR: Memory allocation problem.\n");
  338. }
  339. else
  340. {
  341. /* all is well, go ahead and copy the string */
  342. strcpy(logFile, argv[argc+1]);
  343. }
  344. logFileAllocatedFromHeap=BOOL_TRUE;
  345. }
  346. logfset++;
  347. }
  348. else if (strstr(argv[argc], "-nologfile") != NULL)
  349. {
  350. logDest &= ~LUB_TEST_LOGTOFILE;
  351. logfset++;
  352. }
  353. /* Stdout options */
  354. else if (strstr(argv[argc], "-stdout") != NULL)
  355. {
  356. logDest |= LUB_TEST_LOGTOSTDOUT;
  357. stdset++;
  358. }
  359. else if (strstr(argv[argc], "-nostdout") != NULL)
  360. {
  361. logDest &= ~LUB_TEST_LOGTOSTDOUT;
  362. stdset++;
  363. }
  364. /* Unhandled arguments */
  365. else
  366. {
  367. /* If the next argument down in the list is '-logfile', then
  368. this is the logfile name; don't complain. */
  369. if (strstr(argv[argc-1], "-logfile") == NULL)
  370. {
  371. /* This is an unrecognized option.
  372. Don't bother setting status and forcing an exit; just ignore it. */
  373. fprintf(stderr,"Unrecognized argument: '%s', ignoring it...\n",argv[argc]);
  374. }
  375. }
  376. }
  377. /* See if there is a logging destination */
  378. if (logDest == 0)
  379. {
  380. fprintf(stderr, "WARNING: No logging is enabled to either stdout or a logfile; expect no output.\n");
  381. }
  382. /* Make sure there were no conflicting options */
  383. if (verbset > 1)
  384. {
  385. fprintf(stderr,"ERROR: conflicting lub_test_verbosity_t options specified.\n");
  386. fprintf(stderr," Specify only ONE of -terse, -normal, -verbose\n");
  387. status = BOOL_FALSE;
  388. }
  389. if (failset > 1)
  390. {
  391. fprintf(stderr,"ERROR: conflicting Failure Mode options specified.\n");
  392. fprintf(stderr," Specify only ONE of -stoponfail, -continueonfail\n");
  393. status = BOOL_FALSE;
  394. }
  395. if (logfset > 1)
  396. {
  397. fprintf(stderr,"ERROR: conflicting Logfile options specified.\n");
  398. fprintf(stderr," Specify only ONE of -logfile, -nologfile\n");
  399. status = BOOL_FALSE;
  400. }
  401. if (stdset > 1)
  402. {
  403. fprintf(stderr,"ERROR: conflicting Stdout options specified.\n");
  404. fprintf(stderr," Specify only ONE of -stdout, -nostdout\n");
  405. status = BOOL_FALSE;
  406. }
  407. /* Set up log file, if things are OK so far */
  408. if (status && !TestStartLog(logDest, logFile))
  409. {
  410. status = BOOL_FALSE;
  411. }
  412. if (logFileAllocatedFromHeap)
  413. {
  414. /*lint -e673 Possibly inappropriate deallocation (free) for 'static' data */
  415. free(logFile);
  416. /*lint +e673 */
  417. }
  418. if (BOOL_FALSE == status)
  419. {
  420. fprintf(stderr, "Something bad has occurred. Aborting...\n");
  421. exit(1);
  422. }
  423. }
  424. /*******************************************************
  425. * sequence level functions
  426. ********************************************************/
  427. /* NAME: lub_test_seq_begin
  428. PURPOSE: Starts a new test sequence.
  429. ARGS: num - sequence number, must be different than last one
  430. format, args - printf-style name for the sequence
  431. RETURN: none
  432. */
  433. void
  434. lub_test_seq_begin(int num, const char *seqName, ...)
  435. {
  436. va_list args;
  437. /* Get sequence name */
  438. va_start(args, seqName);
  439. vsprintf(seqDescr, seqName, args);
  440. va_end(args);
  441. /* Start new sequence number */
  442. if (num == seqNum)
  443. {
  444. seqNum++;
  445. unitTestLog(LUB_TEST_TERSE, "seq_start: duplicate sequence number. Using next available sequence number (%d).\n", seqNum);
  446. }
  447. else
  448. {
  449. seqNum = num;
  450. }
  451. /* Reset test number */
  452. testNum = 0;
  453. /* Log beginning of sequence */
  454. lub_test_seq_log(LUB_TEST_NORMAL, "*** Sequence '%s' begins ***", seqDescr);
  455. }
  456. /* NAME: lub_test_seq_end
  457. PURPOSE: Ends current test sequence
  458. ARGS: none
  459. RETURN: none
  460. */
  461. void
  462. lub_test_seq_end(void)
  463. {
  464. lub_test_seq_log(LUB_TEST_NORMAL,
  465. "----------------------------------------"
  466. "--------------------");
  467. }
  468. /* NAME: lub_test_seq_log
  469. PURPOSE: Log output to file and/or stdout, verbosity-filtered and
  470. formatted as a "sequence-level" message
  471. ARGS: level - priority of this message.
  472. Will be logged only if priority equals or exceeds
  473. the current lub_test_verbosity_t level.
  474. format, args - printf-style format and parameters
  475. RETURN: none
  476. */
  477. void
  478. lub_test_seq_log(lub_test_verbosity_t level, const char *format, ...)
  479. {
  480. va_list args;
  481. char string[160];
  482. /* Turn format,args into a string */
  483. va_start(args, format);
  484. vsprintf(string, format, args);
  485. va_end(args);
  486. unitTestLog(level, "%03d : %s", seqNum, string);
  487. }
  488. /*******************************************************
  489. * test level functions
  490. ********************************************************/
  491. /* NAME: lub_test_check
  492. PURPOSE: True/False test of an expression. If True, test passes.
  493. ARGS: expr - expression to evaluate.
  494. format, args - Printf-style format/parameters describing test.
  495. RETURN: Status code - PASS or FAIL
  496. */
  497. lub_test_status_t
  498. lub_test_check(bool_t expr, const char *testName, ...)
  499. {
  500. va_list args;
  501. char testDescr[80];
  502. lub_test_status_t testStatus;
  503. char result[5];
  504. lub_test_verbosity_t verb;
  505. /* evaluate expression */
  506. testStatus = expr ? LUB_TEST_PASS : LUB_TEST_FAIL;
  507. /* extract description as a string */
  508. va_start(args, testName);
  509. vsprintf(testDescr, testName, args);
  510. va_end(args);
  511. /* log results */
  512. if (testStatus == LUB_TEST_PASS)
  513. {
  514. verb=LUB_TEST_NORMAL;
  515. sprintf(result, "pass");
  516. }
  517. else
  518. {
  519. verb=LUB_TEST_TERSE;
  520. sprintf(result, "FAIL");
  521. }
  522. testLogNoIndent(verb, "[%s] %s", result, testDescr);
  523. return checkStatus(testStatus);
  524. }
  525. /* NAME: lub_test_check_int
  526. PURPOSE: Checks whether an integer equals its expected value.
  527. ARGS: expect - expected value.
  528. actual - value being checked.
  529. format, args - Printf-style format/parameters describing test.
  530. RETURN: Status code - PASS or FAIL
  531. */
  532. lub_test_status_t
  533. lub_test_check_int(int expect, int actual, const char *testName, ... )
  534. {
  535. va_list args;
  536. char testDescr[80];
  537. lub_test_status_t testStatus;
  538. char result[5];
  539. char eqne[3];
  540. lub_test_verbosity_t verb;
  541. /* evaluate expression */
  542. testStatus = (expect == actual) ? LUB_TEST_PASS : LUB_TEST_FAIL;
  543. /* extract description as a string */
  544. va_start(args, testName);
  545. vsprintf(testDescr, testName, args);
  546. va_end(args);
  547. /* log results */
  548. if (testStatus == LUB_TEST_PASS)
  549. {
  550. sprintf(result, "pass");
  551. sprintf(eqne, "==");
  552. verb = LUB_TEST_NORMAL;
  553. }
  554. else
  555. {
  556. sprintf(result, "FAIL");
  557. sprintf(eqne, "!=");
  558. verb = LUB_TEST_TERSE;
  559. }
  560. testLogNoIndent(verb, "[%s] (%d%s%d) %s",
  561. result, actual, eqne, expect, testDescr);
  562. return checkStatus(testStatus);
  563. }
  564. /* NAME: lub_test_check_float
  565. PURPOSE: Checks whether a float is within min/max limits.
  566. ARGS: min - minimum acceptable value.
  567. max - maximum acceptable value.
  568. actual - value being checked.
  569. format, args - Printf-style format/parameters describing test.
  570. RETURN: Status code - PASS or FAIL
  571. */
  572. lub_test_status_t
  573. lub_test_check_float(double min, double max, double actual,
  574. const char *testName, ...)
  575. {
  576. va_list args;
  577. char testDescr[80];
  578. lub_test_status_t testStatus;
  579. char result[5];
  580. char gteq[4], lteq[4];
  581. /* evaluate expression */
  582. testStatus = ((actual >= min) && (actual <= max)) ? LUB_TEST_PASS : LUB_TEST_FAIL;
  583. /* extract description as a string */
  584. va_start(args, testName);
  585. vsprintf(testDescr, testName, args);
  586. va_end(args);
  587. /* log results */
  588. if (testStatus == LUB_TEST_PASS)
  589. {
  590. sprintf(result, "pass");
  591. sprintf(gteq, " <=");
  592. sprintf(lteq, " <=");
  593. }
  594. else
  595. {
  596. sprintf(result, "FAIL");
  597. if (actual < min)
  598. {
  599. sprintf(gteq, "!<=");
  600. sprintf(lteq, " <=");
  601. }
  602. else
  603. {
  604. sprintf(gteq, " <=");
  605. sprintf(lteq, "!<=");
  606. }
  607. }
  608. testLogNoIndent(LUB_TEST_NORMAL, "[%s] (%8f%s%8f%s%8f) %s",
  609. result, min, gteq, actual, lteq, max, testDescr);
  610. return checkStatus(testStatus);
  611. }
  612. /* NAME: lub_test_log
  613. PURPOSE: Log output to file and/or stdout, verbosity-filtered and
  614. formatted as a "test-level" message
  615. ARGS: level - priority of this message.
  616. Will be logged only if priority equals or exceeds
  617. the current lub_test_verbosity_t level.
  618. format, args - printf-style format and parameters
  619. RETURN: none
  620. */
  621. void
  622. lub_test_log(lub_test_verbosity_t level, const char *format, ...)
  623. {
  624. va_list args;
  625. char string[160];
  626. /* Turn format,args into a string */
  627. va_start(args, format);
  628. vsprintf(string, format, args);
  629. va_end(args);
  630. unitTestLog(level, "%03d-%04d: %s", seqNum, testNum, string);
  631. }
  632. /* NAME: testLogNoIndent
  633. PURPOSE: Log output to file and/or stdout, verbosity-filtered and
  634. formatted as a "test-level" message.
  635. This "internal" version does not indent, so that the
  636. pass/fail column can be printed in the proper place.
  637. ARGS: level - priority of this message.
  638. Will be logged only if priority equals or exceeds
  639. the current lub_test_verbosity_t level.
  640. format, args - printf-style format and parameters
  641. RETURN: none
  642. */
  643. static void testLogNoIndent(lub_test_verbosity_t level, const char *format, ...)
  644. {
  645. va_list args;
  646. char string[160];
  647. /* Turn format,args into a string */
  648. va_start(args, format);
  649. vsprintf(string, format, args);
  650. va_end(args);
  651. unitTestLog(level, "%03d-%04d: %s", seqNum, testNum, string);
  652. }