checkmk.1 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. .\" This manpage has been automatically generated by docbook2man
  2. .\" from a DocBook document. This tool can be found at:
  3. .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
  4. .\" Please send any bug reports, improvements, comments, patches,
  5. .\" etc. to Steve Cheng <steve@ggi-project.org>.
  6. .TH "CHECKMK" "1" "09 February 2010" "" ""
  7. .SH NAME
  8. checkmk \- Awk script for generating C unit tests for use with the Check unit testing framework.
  9. .SH SYNOPSIS
  10. \fBcheckmk\fR [ \fBclean_mode=1\fR ] [ \fB\fIinput-file\fB\fR ]
  11. .SH "DESCRIPTION"
  12. .PP
  13. Generate C-language source files containing unit tests for use
  14. with the Check unit testing framework. The aim of this script is
  15. to automate away some of the typical boilerplate one must write when
  16. writing a test suite using Check: specifically, the instantiation of
  17. an SRunner, Suite(s), and TCase(s), and the building of
  18. relationships between these objects and the test functions.
  19. .PP
  20. This tool is intended to be used by those who are familiar
  21. with the Check unit testing framework. Familiarity with the
  22. framework will be assumed throughout this manual.
  23. .PP
  24. The Check framework, along with information regarding it, is
  25. available at https://libcheck.github.io/check/ <URL:https://libcheck.github.io/check/>\&.
  26. .PP
  27. The \fIinput-file\fR argument to
  28. \fBcheckmk\fR uses a simple, C-preprocessor-like
  29. syntax to declare test functions, and to describe their
  30. relationships to Suites and TCases in Check.
  31. \fBcheckmk\fR then uses this information to
  32. automatically write a \fBmain()\fR function
  33. containing all of the necessary declarations, and whatever code is
  34. needed to run the test suites. The final C-language output is
  35. printed to \fBcheckmk\fR\&'s standard output.
  36. .PP
  37. Facilities are provided for the insertion of user code into
  38. the generated \fBmain()\fR function, to provide for
  39. the use of logging, test fixtures or specialized exit values.
  40. .PP
  41. While it is possible to omit the
  42. \fIinput-file\fR argument to
  43. \fBcheckmk\fR and provide the input file on
  44. \fBcheckmk\fR\&'s standard input instead, it is generally
  45. recommended to provide it as an argument. Doing this allows
  46. \fBcheckmk\fR to be aware of the file's name, to place
  47. references to it in the initial comments of the C-language output,
  48. and to intersperse C #line directives throughout, to
  49. facilitate in debugging problems by directing the user to the
  50. original input file.
  51. .SH "OPTIONS"
  52. .PP
  53. The only officially supported option is specifying a true
  54. value (using Awk's definition for "true") for the variable
  55. \fBclean_mode\fR\&. This causes \fBcheckmk\fR
  56. not to place appropriate #line directives in the
  57. source code, which some might find to be unnecessary clutter.
  58. .PP
  59. The author recommends against the use of this option, as it
  60. will cause C compilers and debugging tools to refer to lines in the
  61. automatically generated output, rather than the original input files
  62. to \fBcheckmk\fR\&. This would encourage users to edit the
  63. output files instead of the original input files, would make it
  64. difficult for intelligent editors or IDEs to pull up the right file
  65. to edit, and could result in the fixes being overwritten when the
  66. output files are regenerated.
  67. .PP
  68. #line directives are automatically
  69. suppressed when the input file is provided on standard input
  70. instead of as a command-line argument.
  71. .SH "BASIC EXAMPLE"
  72. .PP
  73. In its most basic form, an input file can be simply a
  74. prologue and a test function. Anything that appears before the
  75. first test function is in the prologue, and will be copied into
  76. the output verbatim. The test function is begun by a line in the
  77. form:
  78. .nf
  79. #test \fItest_name\fR
  80. .fi
  81. .PP
  82. Where \fItest_name\fR is the name of
  83. your test function. This will be used to name a C function, so
  84. it must be a valid C identifier.
  85. .PP
  86. Here is a small, complete example:
  87. .nf
  88. --------------------------------------------------
  89. /* A complete test example */
  90. #include <stdio.h>
  91. #test the_test
  92. int nc;
  93. const char msg[] = "\\n\\n Hello, world!\\n";
  94. nc = printf("%s", msg);
  95. ck_assert(nc == (sizeof(msg) - 1)); /* for terminating NUL. */
  96. --------------------------------------------------
  97. .fi
  98. .PP
  99. If you place the above into a file named
  100. \fIbasic_complete.ts\fR and process it using the
  101. following command:
  102. .PP
  103. \fB$ checkmk basic_complete.ts > basic_complete.c\fR
  104. .PP
  105. \fIbasic_complete.c\fR
  106. will contain output similar to:
  107. .nf
  108. --------------------------------------------------
  109. /*
  110. * DO NOT EDIT THIS FILE. Generated by checkmk.
  111. * Edit the original source file "in" instead.
  112. */
  113. #include <check.h>
  114. /* A complete test example */
  115. #include <stdio.h>
  116. START_TEST(the_test)
  117. {
  118. int nc;
  119. const char msg[] = "\\n\\n Hello, world!\\n";
  120. nc = printf("%s", msg);
  121. ck_assert(nc == (sizeof(msg) - 1)); /* for terminating NUL. */
  122. }
  123. END_TEST
  124. int main(void)
  125. {
  126. Suite *s1 = suite_create("Core");
  127. TCase *tc1_1 = tcase_create("Core");
  128. SRunner *sr = srunner_create(s1);
  129. int nf;
  130. suite_add_tcase(s1, tc1_1);
  131. tcase_add_test(tc1_1, the_test);
  132. srunner_run_all(sr, CK_ENV);
  133. nf = srunner_ntests_failed(sr);
  134. srunner_free(sr);
  135. return nf == 0 ? 0 : 1;
  136. }
  137. --------------------------------------------------
  138. .fi
  139. .PP
  140. In real usage, \fIbasic_complete.c\fR would
  141. also contain #line directives.
  142. .SH "DIRECTIVE SUMMARY"
  143. .PP
  144. Here is a complete summary of all the C-preprocessor-style
  145. directives that are understood by \fBcheckmk\fR\&. See
  146. below for more details.
  147. .nf
  148. # test \fItest_name\fR
  149. # test-signal(\fIsignal\fR) \fItest_name\fR
  150. # test-exit(\fIexit_code\fR) \fItest_name\fR
  151. # test-loop(\fIstart\fR, \fIend\fR) \fItest_name\fR
  152. # test-loop-signal(\fIsignal\fR, \fIstart\fR, \fIend\fR) \fItest_name\fR
  153. # test-loop-exit(\fIexit_code\fR, \fIstart\fR, \fIend\fR) \fItest_name\fR
  154. # suite \fITestSuiteName\fR
  155. # tcase \fITestCaseName\fR
  156. # main-pre
  157. # main-post
  158. .fi
  159. .PP
  160. All directives are case-insensitive. Whitespace may appear
  161. at the beginning of the line before the #,
  162. between the # and the directive, between the
  163. directive and any argument, and at the end of the line.
  164. .SH "TEST-DEFINING DIRECTIVES"
  165. .PP
  166. Here is a more detailed explanation of the directives that may be
  167. used to define test functions and their containers.
  168. .SS "TEST FUNCTIONS"
  169. .nf
  170. # test \fItest_name\fR
  171. # test-signal(\fIsignal\fR) \fItest_name\fR
  172. # test-exit(\fIexit_code\fR) \fItest_name\fR
  173. # test-loop(\fIstart\fR, \fIend\fR) \fItest_name\fR
  174. # test-loop-signal(\fIsignal\fR, \fIstart\fR, \fIend\fR) \fItest_name\fR
  175. # test-loop-exit(\fIexit_code\fR, \fIstart\fR, \fIend\fR) \fItest_name\fR
  176. .fi
  177. .PP
  178. These are the most basic directives for creating a template
  179. for input to \fBcheckmk\fR\&. They are the only
  180. directives that are required: there must be at least one
  181. #test* directive appearing in the template, or
  182. \fBcheckmk\fR will fail with an error message. The
  183. #test* directives may be specified several times,
  184. each one beginning the definition of a new test function.
  185. .PP
  186. The \fItest_name\fR argument will be
  187. used as the name of a test function in the C-language output, so
  188. it must be a valid C identifier. That is, it must begin with an
  189. alphabetic character or the underscore (_),
  190. followed by optional alpha-numeric characters and/or
  191. underscores.
  192. .PP
  193. Universal Character Names (introduced in C99) are also
  194. allowed, of the form \\uXXXX or
  195. \\UXXXXXXXX, where the X\&'s
  196. represent hexadecimal digits.
  197. .PP
  198. It is an error to specify the same
  199. \fItest_name\fR in more than one
  200. #test* directive, regardless of whether they
  201. are associated with different test cases or suites.
  202. .PP
  203. See CHECKMK
  204. IDENTIFIERS for the list of identifiers which should be
  205. avoided for use as test function names.
  206. .SS "TEST SUITES"
  207. .nf
  208. # suite \fITestSuiteName\fR
  209. .fi
  210. .PP
  211. This directive specifies the name of the test suite
  212. (\fBSuite\fR object in the Check test
  213. framework) to which all future test cases (and their test
  214. functions) will be added.
  215. .PP
  216. The \fITestSuiteName\fR is a text
  217. string, and may contain any sort of characters at all (other
  218. than ASCII NUL character, and the newline, which would terminate
  219. the directive). Any leading or trailing whitespace will be omitted
  220. from the test suite name.
  221. .PP
  222. Starting a new test suite also begins a new test case, whose
  223. name is identical to the new test suite. This test case name may be
  224. overridden by a subsequent #tcase directive.
  225. .PP
  226. Note that a \fBSuite\fR object won't
  227. actually be defined by \fBcheckmk\fR in the C
  228. output, unless it is followed at some point by a
  229. #test directive (without an intervening
  230. #suite). It is not an error for a
  231. #suite to have no associated
  232. #test\&'s; the #suite (and any
  233. associated #tcase\&'s) simply won't result in any
  234. action on the part of \fBcheckmk\fR (and would
  235. therefore be useless).
  236. .PP
  237. It is an error for a #suite directive to
  238. specify the same (case sensitive) suite multiple times, unless the
  239. previous uses were not instantiated by the presence of at least
  240. one associated #test directive.
  241. .PP
  242. If you do not specify a #suite directive
  243. before the first #test directive,
  244. \fBcheckmk\fR performs the equivalent of an
  245. implicit #suite directive, with the string
  246. "Core" as the value for
  247. \fITestSuiteName\fR (this also implies a
  248. "Core" test case object). This is demonstrated
  249. above in BASIC EXAMPLE\&.
  250. .SS "TEST CASES"
  251. .nf
  252. # tcase \fITestCaseName\fR
  253. .fi
  254. .PP
  255. This directive specifies the name of the test case
  256. (\fBTCase\fR object in the Check test
  257. framework) to which all future test functions will be added.
  258. .PP
  259. The #tcase works very in a way very
  260. similar to #suite\&. The
  261. \fITestCaseName\fR is a text string, and
  262. may contain arbitrary characters; and a
  263. \fBTCase\fR object won't actually be defined
  264. unless it is followed by an associated
  265. #test directive.
  266. .PP
  267. It is an error for a #tcase directive to
  268. specify the same (case sensitive) test case multiple times, unless the
  269. previous uses were not instantiated by the presence of at least
  270. one associated #test directive.
  271. .PP
  272. See also the #suite directive, described
  273. above.
  274. .SH "USER CODE IN MAIN()"
  275. .PP
  276. The C \fBmain()\fR is automatically generated
  277. by \fBcheckmk\fR, defining the necessary
  278. \fBSRunner\fR\&'s, \fBSuite\fR\&'s,
  279. and\~\fBTCase\fR\&'s required by the
  280. test-defining directives specified by the user.
  281. .PP
  282. For most situations, this completely automated
  283. \fBmain()\fR is quite suitable as-is. However,
  284. there are situations where one might wish to add custom code to
  285. the \fBmain()\fR\&. For instance, if the user wishes
  286. to:
  287. .TP 0.2i
  288. \(bu
  289. change the test timeout value via
  290. \fBtcase_set_timeout()\fR,
  291. .TP 0.2i
  292. \(bu
  293. specify Check's "no-fork-mode" via
  294. \fBsrunner_set_fork_status()\fR,
  295. .TP 0.2i
  296. \(bu
  297. set up test fixtures for some test cases, via
  298. \fBtcase_add_checked_fixture()\fR
  299. or\~\fBtcase_add_unchecked_fixture()\fR,
  300. .TP 0.2i
  301. \(bu
  302. set up test logging for the suite
  303. runner, via \fBsrunner_set_log()\fR
  304. or\~\fBsrunner_set_xml()\fR, or
  305. .TP 0.2i
  306. \(bu
  307. perform custom wrap-up after the test suites have
  308. been run.
  309. .PP
  310. For these purposes, the #main-pre
  311. and\~#main-post directives have been
  312. provided.
  313. .SS "MAIN() PROLOGUE"
  314. .nf
  315. # main-pre
  316. .fi
  317. .PP
  318. The text following this directive will be placed verbatim
  319. into the body of the generated \fBmain()\fR
  320. function, just after \fBcheckmk\fR\&'s own local
  321. variable declarations, and before any test running has taken
  322. place (indeed, before even the relationships between the tests,
  323. test cases, and test suites have been set up, though that
  324. fact shouldn't make much difference). Since
  325. \fBcheckmk\fR has only just finished making its
  326. declarations, it is permissible, even under strict 1990 ISO C
  327. guidelines, to make custom variable declarations here.
  328. .PP
  329. Unlike the previously-described directives,
  330. #main-pre may be specified at most once. It may
  331. not be preceded by the #main-post directive,
  332. and no #suite, #tcase,
  333. or #test directive may appear after it.
  334. .PP
  335. #main-pre is a good place to tweak
  336. settings or set up test fixtures. Of course, in order to do so,
  337. you need to know what names \fBcheckmk\fR has used
  338. to instantiate the \fBSRunner\fR\&'s,
  339. \fBSuite\fR\&'s,
  340. and\~\fBTCase\fR\&'s.
  341. .SS "CHECKMK IDENTIFIERS"
  342. .PP
  343. Pointers to \fBSuite\fR\&'s are declared
  344. using the pattern
  345. s\fIX\fR, where
  346. \fIX\fR is a number
  347. that starts at 1, and is incremented for each subsequent
  348. #suite directive.
  349. s1 always exists, and contains the test
  350. function declared by the first #test
  351. directive. If that directive was not preceded by a
  352. #suite, it will be given the name "Core".
  353. .PP
  354. Pointers to \fBTCase\fR\&'s are declared
  355. using the pattern
  356. tc\fIX\fR_\fIY\fR,
  357. where \fIX\fR corresponds to the number
  358. used for the name of the \fBSuite\fR that
  359. will contain this \fBTCase\fR; and
  360. \fIY\fR is a number that starts at 1 for
  361. each new \fBSuite\fR, and is incremented for
  362. each \fBTCase\fR in that
  363. \fBSuite\fR\&.
  364. .PP
  365. A pointer to \fBSRunner\fR is declared
  366. using the identifier sr; there is also an
  367. integer named nf which holds the number of
  368. test failures (after the tests have run).
  369. .PP
  370. For obvious reasons, the user should not attempt to
  371. declare local identifiers in \fBmain()\fR, or
  372. define any macros or test functions, whose names might
  373. conflict with the local variable names used by
  374. \fBcheckmk\fR\&. To summarize, these names are:
  375. s\fIX\fR
  376. tc\fIX\fR_\fIY\fR
  377. sr
  378. nf\&.
  379. .SS "MAIN() EPILOGUE"
  380. .nf
  381. # main-post
  382. .fi
  383. .PP
  384. Though it is not as useful, \fBcheckmk\fR also
  385. provides a #main-post directive to insert
  386. custom code at the end of \fBmain()\fR, after the
  387. tests have run. This could be used to clean up resources that
  388. were allocated in the prologue, or to print information about
  389. the failed tests, or to provide a custom exit status
  390. code.
  391. .PP
  392. Note that, if you make use of this directive,
  393. \fBcheckmk\fR will \fBnot\fR provide a
  394. return statement: you will need
  395. to provide one yourself.
  396. .PP
  397. The #main-post directive may not be
  398. followed by any other directives recognized by
  399. \fBcheckmk\fR\&.
  400. .SH "COMPREHENSIVE EXAMPLE"
  401. .PP
  402. Now that you've gotten the detailed descriptions of the
  403. various directives, let's see it all put to action with this
  404. fairly comprehensive template.
  405. .nf
  406. --------------------------------------------------
  407. #include "mempool.h" /* defines MEMPOOLSZ, prototypes for
  408. mempool_init() and mempool_free() */
  409. void *mempool;
  410. void mp_setup(void)
  411. {
  412. mempool = mempool_init(MEMPOOLSZ);
  413. ck_assert_msg(mempool != NULL, "Couldn't allocate mempool.");
  414. }
  415. void mp_teardown(void)
  416. {
  417. mempool_free(mempool);
  418. }
  419. /* end of prologue */
  420. #suite Mempool
  421. #tcase MP Init
  422. #test mempool_init_zero_test
  423. mempool = mempool_init(0);
  424. ck_assert_msg(mempool == NULL, "Allocated a zero-sized mempool!");
  425. ck_assert_msg(mempool_error(), "Didn't get an error for zero alloc.");
  426. /* "MP Util" TCase uses checked fixture. */
  427. #tcase MP Util
  428. #test mempool_copy_test
  429. void *cp = mempool_copy(mempool);
  430. ck_assert_msg(cp != NULL, "Couldn't perform mempool copy.");
  431. ck_assert_msg(cp != mempool, "Copy returned original pointer!");
  432. #test mempool_size_test
  433. ck_assert(mempool_getsize(mempool) == MEMPOOLSZ);
  434. #main-pre
  435. tcase_add_checked_fixture(tc1_2, mp_setup, mp_teardown);
  436. srunner_set_log(sr, "mplog.txt");
  437. #main-post
  438. if (nf != 0) {
  439. printf("Hey, something's wrong! %d whole tests failed!\\n", nf);
  440. }
  441. return 0; /* Harness checks for output, always return success
  442. regardless. */
  443. --------------------------------------------------
  444. .fi
  445. .PP
  446. Plugging this into \fBcheckmk\fR, we'll get
  447. output roughly like the following:
  448. .nf
  449. --------------------------------------------------
  450. /*
  451. * DO NOT EDIT THIS FILE. Generated by checkmk.
  452. * Edit the original source file "comprehensive.ts" instead.
  453. */
  454. #include <check.h>
  455. #include "mempool.h"
  456. void *mempool;
  457. void mp_setup(void)
  458. {
  459. \&...
  460. }
  461. void mp_teardown(void)
  462. {
  463. \&...
  464. }
  465. /* end of prologue */
  466. START_TEST(mempool_init_zero_test)
  467. {
  468. \&...
  469. }
  470. END_TEST
  471. START_TEST(mempool_copy_test)
  472. {
  473. \&...
  474. }
  475. END_TEST
  476. START_TEST(mempool_size_test)
  477. {
  478. \&...
  479. }
  480. END_TEST
  481. int main(void)
  482. {
  483. Suite *s1 = suite_create("Mempool");
  484. TCase *tc1_1 = tcase_create("MP Init");
  485. TCase *tc1_2 = tcase_create("MP Util");
  486. SRunner *sr = srunner_create(s1);
  487. int nf;
  488. /* User-specified pre-run code */
  489. tcase_add_checked_fixture(tc1_2, mp_setup, mp_teardown);
  490. srunner_set_log(sr, "mplog.txt");
  491. suite_add_tcase(s1, tc1_1);
  492. tcase_add_test(tc1_1, mempool_init_zero_test);
  493. suite_add_tcase(s1, tc1_2);
  494. tcase_add_test(tc1_2, mempool_copy_test);
  495. tcase_add_test(tc1_2, mempool_size_test);
  496. srunner_run_all(sr, CK_ENV);
  497. nf = srunner_ntests_failed(sr);
  498. srunner_free(sr);
  499. /* User-specified post-run code */
  500. if (nf != 0) {
  501. printf("Hey, something's wrong! %d whole tests failed!\\n", nf);
  502. }
  503. return 0; /* Harness checks for output, always return success
  504. regardless. */
  505. }
  506. --------------------------------------------------
  507. .fi
  508. .SH "AUTHOR"
  509. .PP
  510. \fBcheckmk\fR and this manual were written
  511. by Micah J Cowan.
  512. .PP
  513. Copyright (C) 2006, 2010 Micah J Cowan.