3 .\" Manual for the test vector framework
5 .\" (c) 2024 Straylight/Edgeware
8 .\"----- Licensing notice ---------------------------------------------------
10 .\" This file is part of the mLib utilities library.
12 .\" mLib is free software: you can redistribute it and/or modify it under
13 .\" the terms of the GNU Library General Public License as published by
14 .\" the Free Software Foundation; either version 2 of the License, or (at
15 .\" your option) any later version.
17 .\" mLib is distributed in the hope that it will be useful, but WITHOUT
18 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 .\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 .\" License for more details.
22 .\" You should have received a copy of the GNU Library General Public
23 .\" License along with mLib. If not, write to the Free Software
24 .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
30 .\"--------------------------------------------------------------------------
31 .TH tvec 3mLib "11 March 2024" "Straylight/Edgeware" "mLib utilities library"
51 .\"--------------------------------------------------------------------------
53 tvec \- test vector framework
55 .\"--------------------------------------------------------------------------
58 .B "#include <mLib/tvec.h>"
61 .B "union tvec_misc {"
64 .B " unsigned long u;"
77 .B "union tvec_regval {"
79 .B " unsigned long u;"
82 .B " struct { char *p; size_t sz; } text;"
83 .B " struct { unsigned char *p; size_t sz; } bytes;"
85 .B " unsigned char *p; size_t sz;"
91 .B "struct tvec_reg {"
93 .B " union tvec_regval v;"
95 .B "#define TVRF_SEEN ..."
96 .B "#define TVRF_LIVE ..."
99 .B "struct tvec_regdef {"
100 .B " const char *name;"
101 .B " const struct tvec_regty *ty;"
104 .B " union tvec_misc arg;"
106 .B "#define TVRF_UNSET ..."
107 .B "#define TVRF_OPT ..."
108 .B "#define TVRF_ID ..."
109 .B "#define TVEC_ENDREGS ..."
111 .B "struct tvec_state;"
113 .B "struct tvec_env;"
114 .ta \w'\fBtypedef void tvec_testfn('u
115 .BI "typedef void tvec_testfn(const struct tvec_reg *" in ,
116 .BI " struct tvec_reg *" out ,
119 .B "struct tvec_test {"
120 .B " const char *name;"
121 .B " const struct tvec_regdef *regs;"
122 .B " const struct tvec_env *env;"
123 .B " tvec_testfn *fn;"
127 .B "struct tvec_config {"
128 .B " const struct tvec_test *const *tests;"
129 .B " unsigned nrout, nreg;"
132 .B "struct tvec_output;"
134 .ta \w'\fBvoid tvec_begin('u
135 .BI "void tvec_begin(struct tvec_state *" tv_out ,
136 .BI " const struct tvec_config *" config ,
137 .BI " struct tvec_output *" o );
138 .BI "int tvec_end(struct tvec_state *" tv );
139 .BI "int tvec_read(struct tvec_state *" tv ", const char *" infile ", FILE *" fp );
141 .B "#define TVHF_TTY ..."
142 .B "#define TVHF_COLOUR ..."
143 .ta \w'\fBstruct tvec_output *tvec_humanoutput('u
144 .BI "struct tvec_output *tvec_humanoutput(FILE *" fp ,
145 .BI " unsigned " f ", unsigned " m );
146 .BI "struct tvec_output *tvec_machineoutput(FILE *" fp );
147 .BI "struct tvec_output *tvec_tapoutput(FILE *" fp );
148 .BI "struct tvec_output *tvec_dfltoutput(FILE *" fp );
151 .B "struct tvec_amargs {"
153 .B " const char *name;"
157 .BI "struct tvec_output *tvec_amoutput(const struct tvec_amargs *" a );
160 .\"--------------------------------------------------------------------------
165 header file provides definitions and declarations
166 for the core of mLib's
167 .IR "test vector framework" .
169 The test vector framework is rather large and complicated,
170 so the documentation for it is split into multiple manual pages.
171 This one provides a conceptual overview
172 and describes the essentials for using it to build simple tests.
174 .SS Conceptual overview
177 runs a collection of tests
178 and reports on the outcome.
182 involves exercising some functionality
183 and checking that it behaves properly.
188 the functionality behaved properly.
191 the functionality did not behave properly.
193 .IR "expected failure" :
194 the functionality behaved as expected,
195 but the expected behaviour is known to be incorrect.
198 for some reason, the test couldn't be performed.
200 Tests are gathered together into
202 Each test group has a name.
203 Like a individual tests, test groups also have outcomes:
204 they can pass, fail, or be skipped.
205 A test group cannot experience expected failure.
207 A session may also encounter
209 e.g., as a result of malformed input
210 or failures reported by system facilities,
211 which prevent proper testing from proceeding.
212 The framework attempts to recover from errors,
213 so as to provide as useful a result as possible;
215 an error means that the test results are inconclusive.
217 A test session can either
218 be driven from data provided by an input file,
219 or it can be driven by the program alone.
220 The latter case is called
224 This manual page describes file-driven testing.
226 When it begins a session for file-directed testing,
227 the program provides a table of
228 .IR "test definitions" .
229 A test definition has a
232 .IR "test function" ,
234 .IR "test environment" ,
236 .IR "register definitions" .
237 Test environments are explained further below.
241 is a place which can store a single item of test data;
242 registers are the means
243 by which input test data is provided to a test function,
244 and by which a test function returns its results.
245 A test definition's register definitions
246 establish a collection of
249 Each active register has a
255 which are established by its register definition.
256 The register's name is used to refer to the register in the test data file,
257 and its index is used to refer to it
258 in the test function and test environments.
259 The register's type describes the acceptable values for the register,
260 and how they are to be compared,
261 read from the input file,
262 and dumped in diagnostic output.
263 New register types can be defined fairly easily: see
266 A register definition may describe an
271 input registers provide input data to the test function, while
272 output registers collect output data from the test function.
273 The data file provides values for both input and output registers:
274 the values for the input registers are passed to the test function;
275 the values for the output registers are
277 values against which the test function's outputs are to be checked.
279 The test function is called with two vectors of registers,
280 one containing input values for the test function to read
281 and also reference values,
282 and another for output values that the test function should write;
285 provided by the test environment.
286 The test function's task is to exercise the functionality to be tested,
287 providing it the input data from its input registers,
288 and collecting the output in its output registers.
289 It is the responsibility of the test environment or the framework
290 to compare the output register values against reference
291 provided in the input data.
293 The input file syntax is described in full below.
297 Comments begin with a semicolon character
299 and extend to the end of the line.
302 by headings in square brackets:
306 Each section contains a number of
308 separated by blank lines.
309 Each paragraph consists of one or more
319 When the framework encounters a section heading,
320 it finishes any test group currently in progress,
321 and searches for a test definition whose name matches the
323 name in the section heading.
325 it begins a new test group with the same name.
326 Each paragraph of assignments is used to provide
327 input and reference values
331 name in an assignment must match the name
332 of an active register or a
333 .I "special variable" ;
336 is stored in the named register or variable.
338 A register which has been assigned a value is said to be
342 By default, every active register must be live for a test to proceed;
343 but a register definition can mark its register as
347 An optional register need not be assigned a value explicitly;
348 instead, the register is left dead.
349 A may-be-unset register must be mentioned,
350 but a distinctive syntax
354 (with no colon or equals sign)
355 says that the register should be left dead.
356 Optional registers are suitable for cases where
357 there is an obvious default value
358 which would otherwise be mentioned frequently in input files.
359 May-be-unset registers are mostly useful as outputs,
360 where the output is not always set,
361 e.g., in error cases,
362 but where omitting a value in the usual case is likely a mistake.
364 A test environment fits in between
365 the framework and the test function.
366 It can establish hook functions which are called
367 at various points throughout a test group
368 (at the start and and, and before and after each test).
369 It can define special variables
370 which can be set from the input file using assignments.
371 And, finally, it can take on the responsibility
372 of running the test function.
373 The registers will have been set up already,
374 based on the assignments in the input file,
375 but the environment can modify them.
376 It must also check the test function's output
377 against the reference values,
378 though there are functions provided for doing this.
379 The environment can choose to run the test function once,
380 multiple times, or, indeed, not at all.
381 When it calls the test function, it can provide a context pointer,
382 with whatever additional information might be useful:
383 this usually involves coordination
384 between the environment and the test function.
385 It is the test environment's responsibility
386 to check the outputs returned by the test function
387 and to report on mismatches,
388 but there are functions provided by the framework
389 to do the heavy lifting.
391 The following are examples of what test environments can do.
393 It can fill in default values for optional dead registers.
394 For example, if a function returnns error codes,
395 then you can save reptition in the input file
396 by marking the error-code output register optional
397 and letting it default to the `success' value in a test environment.
399 It can run the test function mulitple times.
400 For example, a test of functions like
402 might run the test twice,
403 first with its operands as supplied by the input file,
404 and then again with the operands swapped
405 and the opposite expected result.
406 A test for bignum addition could verify commutativity
407 by checking both that
408 .IR x "\ + \ " y "\ =\ " z
410 .IR y "\ + \ " x "\ =\ " z \fR.
411 Similarly, a subtraction test could check both that
412 .IR x "\ \- \ " y "\ =\ " z
414 .IR y "\ \- \ " x "\ =\ \-" z \fR.
418 .BR tvec-timeout (3),
421 extensions all slot in as test environments,
422 with no extensions to the core API.
424 The framework includes a simple command-line front-end
429 function provides all of the necessary command-line
430 option and argument processing,
431 and handles the test session lifecycle,
432 given a pointer to the static tables
433 describing the supported test groups.
435 .SS Input file format
436 The file format is inspired by Windows
440 Comments begin with a semicolon
442 and continue to the end of the line;
443 a comment may be placed on a line by itself,
444 optionally preceded by whitespace;
445 or following other contents on a line.
447 Indentation and blank lines are significant;
448 trailing whitespace on a line is generally ignored.
449 Blank lines serve to separate groups of assignments into `paragraphs'
451 A line containing only a comment,
452 possibly preceded by whitespace,
454 and does not separate paragraphs.
455 An indented line is a
456 .IR "continuation line" ,
457 used to continue values over multiple lines.
459 A line beginning with an opening square bracket
462 .IR "section heading" ,
467 optionally followed by a comment.
470 may consist of any non-whitespace characters
471 other than the closing square bracket
473 Whitespace is permitted
474 (though not recommended)
475 between the brackets and the
479 must match the name of a test group
480 defined by the test configuration;
483 A section heading marks the start of a
485 which continues until the next section heading
486 or to the end of the file.
488 Each section consists of
492 by groups of one or more blank lines.
493 A line containing only a comment is
495 considered to be `blank' for the purposes of separating paragraphs.
496 There need not be blank lines
497 before the first paragraph in a section;
500 A paragraph consists of one or more
502 each of which begins with an unindented
504 followed by zero or more indented
505 .IR "continuation lines" .
507 An initial line begins with a
510 .IR "assignment operator" ;
511 the remaining contents, if any,
512 are determined by the name and operator.
513 A name is a sequence of non-whitespace characters
514 other than assignment operators, which are
521 There may be whitespace separating the name and operator.
524 .I "value assignment"
530 there is no difference in meaning between the two.
531 The operator is followed by optional whitespace and a
535 must match the name of a register or special variable
536 defined by the test group,
537 and the register or special variable definition determines
538 a register type for the assignment;
539 the syntax of the value is determined by the register type;
542 for the descriptions of the built-in types,
545 for how to define new register types.
548 may continue over multiple continuation lines,
549 each beginning with one or more whitespace characters.
550 The effect is to set the named register or special variable
551 to the specified value.
560 must match the name of a regsiter defined by the test group.
561 Only registers defined with the
565 flags (see below) can be unassigned;
566 special variables cannot be unassigned.
568 An error is reported if
569 the same register or special variable
570 is the subject of more than one assignment
572 or if there is no assignment for
573 a register defined by the test group
578 .SS Miscellaneous values
581 is a small union used
582 to pass a simple but opaque parameter
587 signed and unsigned integers
591 and a floating-point number
593 The pointer member is listed first,
594 because this is the most common (and general) case,
595 and the first member of a union
596 is the only member that can be initialized statically
597 in dialects (e.g., C89, C++14) which lack designated initializers.
599 There is an associated collection of constants,
605 which can be used to keep track of which member of a
608 These constants are currently not used by the framework.
613 is essentially a `slot' capable of holding a value.
614 Registers primarily occur as inputs and outputs for test functions,
615 but they also appear in other contexts.
617 The values that a particular register can hold
618 are determined by the register's
620 Register values are held in a
621 .BR "union tvec_regval" .
623 this union contains a number of useful C-level data types
624 corresponding to the provided register types;
625 see the synopsis above, and
628 More members can added by defining the macro
630 to the list of member declarations
634 A register value can hold resources,
635 such as allocated memory,
636 or even network connections or files.
637 A register value must be
642 when it is no longer required.
643 The life-cycle for register values is described in detail in
646 The state of a register is maintained in
647 .BR "struct tvec_reg" ,
648 which contains a flags word
651 .B "union tvec_regval"
654 At the start of the test session,
655 the framework allocates two vectors of
656 .B "struct tvec_reg" ,
665 specified in the test configuration.
668 vector must be at least as long as the
671 .BR nreg "\ \*(>=\ " nrout .
672 Within the framework,
673 registers are identified by their indices in these vectors.
675 .BI \fR0 "\ \*(<=\ " i "\ <\ " nrout
679 .BI nrout "\ \*(<=\ " i "\ <\ " nreg
682 other indices are invalid.
685 .I "register definition"
686 associates a name, type, and some flags, with a register index.
687 A register definitions is represented as a
688 .B "struct tvec_regdef"
689 structure, which has five members.
691 .B "const char *name"
693 This is used in input files to refer to the register.
695 .B "const struct tvec_regty *ty"
697 This can be the address one of the supplied
699 type structures described in
704 for how to implement new types.
707 The index of the register.
710 Flags defining additional special behaviour for the register.
711 The flags are described below.
713 .B "union tvec_misc arg"
714 An argument for the register type.
716 A test definition (see below) includes
717 a vector of register definitions.
718 The vector is terminated by an entry whose
720 member is a null pointer.
723 macro expands to a suitable static initializer.
725 The names and indices of register definitions
726 for a single test definition
728 A test definition need not include
729 a register definition for every register index;
730 the registers with associated definitions
734 those without a definition are said to be
736 Nothing useful can be done with inactive register indices:
737 inactive register don't even have an associated type.
739 The flags which can be set are as follows.
744 the register in input file paragraph
750 It is permitted for an input file paragraph
751 to have no assignment for the register.
752 It is also permitted for an input file paragraph
753 to unassign the register explicitly,
756 additionally implies the behaviour of
760 The register value constitutes part of
761 the `identity' of the test case.
764 uses the values of the registers whose
766 flag is set to label its performence results.
770 vector receives data from the input file.
771 When the framework processes an assignment,
774 in the register definitions:
776 it uses the associated index to locate the register.
777 In the case of a value assignment,
778 the framework invokes the register type's
780 function to read the value from the input file
784 and store it in the register.
785 If this is successful, then the framework sets the
789 flags on the register.
790 In the case of an unassignment,
791 the framework sets only the
794 Registers with indicess equal or greater than
796 provide input data to the test function.
797 Registers with indices less than
799 hold reference values:
800 a test function won't usually inspect these,
802 e.g., to determine an output buffer size.
804 Once the end of the paragraph is found,
805 the framework checks that
806 all of the necessary register have been assigned:
807 every register listed in the test group's register definitions
810 flag set, unless the definition sets the
813 It invokes the test function,
814 via the test environment, if one is defined.
815 See below for details on how the test function is invoked.
820 describes a test group.
821 Test definitions are represented as a
822 .B "struct tvec_test"
824 This has four members.
826 .B "const char *name"
828 This is used in input files to refer to the test group.
830 .B "const struct tvec_regdef *regs"
831 Pointer to the vector of register definitions.
832 The vector is terminated by an entry whose
836 .B "const struct tvec_env *env"
837 Pointer to the test environment for this test group.
838 Test environments are described in
840 Specific uses are discussed in
844 .BR tvec-timeout (3).
850 The signature for test functions is
853 .ta \w'\fBvoid \,\fItestfn\/\fB('u
854 .BI "void " testfn "(const struct tvec_reg *" in ,
855 .BI " struct tvec_rec_reg *" out ", void *" ctx );
862 arguments are the two register vectors discussed above,
863 the former holding the input and reference values,
864 and the latter for the outputs.
867 pointer is provided by the test environment.
868 If there is no test environment,
871 On entry to the test function,
872 all of the active registers are initialized,
879 registers corresponding to
880 live reference registers in the
882 additionally have their
886 Recall that an input-file paragraph can provide
887 a value assignment for a register,
890 A test function or test environment
891 can distinguish the three cases using the register flags:
893 A register which has been assigned a value
900 A register which has been explicitly unassigned has only the
903 Such a register's definition must have had either
909 A register which has not been assigned has neither flag set.
910 Such a register's definition must have had the
914 The test function will usually set the
916 registers corresponding to at least the live reference registers;
917 it may set additional active output registers
922 The caller will check the outputs
923 against the reference values from the input file.
926 occurs when a reference-value register is live and
927 either the corresponding output register is not live
928 or the output register value is not equal to the reference value
929 (as determined by the register type).
930 In the event of a mismatch,
931 the framework dumps the values of of the registers
932 and reports a failure.
936 passed a pointer to the
937 .B "struct tvec_state"
938 structure which is pretty much ubiquitous
939 in the test-vector framework interface.
940 A test function is not expected to `fail'
941 in the sense that it encounters a problem
942 that prevents it from performing the test.
943 Failure-prone setup can be performed by the test environment,
944 which can force a skip if necessary;
945 successfully acquired resources can be passed on
946 to the test function via the context pointer.
947 Errors encountered by the test function itself
948 should usually be reported by setting an output register.
949 If a test function really needs access to the test state,
950 an environment can arrange to pass it in via the context pointer.
952 .SS Test configurations
954 .IR "test configuration" ,
956 .B "struct tvec_config"
958 describes the global information required for a test session.
961 .B "const struct tvec_test *const *tests"
962 A pointer to a vector of pointers to test definitions,
963 terminated by a null pointer.
964 (Having pointers to the test definitions here,
965 rather than the definitions themselves,
966 allows the actual definitions to be kept alongside
967 the rest of the machinery required for the test group.)
970 The number of output registers.
973 The number of registers total.
975 .BR nreg "\ \-\ " nrout
980 .BR "struct tvec_reg" .
981 The fact that a test program can add
982 additional members to the
983 .B "union tvec_regval"
986 means that the true size of the union
987 was unknown when the framework
988 and application-agnostic extensions
990 They therefore need to learn the true size at runtime.
991 Since the main motivation is to be able to index the
997 .BR "struct tvec_reg" ,
999 .B "union tvec_regval"
1001 that's of critical importance.
1004 The framework core does no output itself.
1005 Instead, all output is performed by an
1006 .IR "output driver" ,
1007 represented with the
1008 .B "struct tvec_output"
1012 for details about this structure
1013 and how to write new output drivers.
1014 This section describes the output drivers
1015 provided with the framework.
1023 and returns an output driver chosen in some unspecified way.
1026 refers to an `interactive device'
1027 then the `human' driver is chosen;
1028 otherwise, the `machine' driver is chosen.
1029 This behaviour may change in the future.
1030 If your program depends on a specific driver being chosen,
1031 then use it explicitly.
1033 The predefined drivers are as follows.
1034 .IP The `human' driver
1036 The `human' driver produces output expected to be useful to humans,
1039 unambiguous (I think)
1040 is probably rather difficult to parse.
1041 Moreover, the details of the output are subject to change.
1043 The `human' driver prints a line when a test or test group is skipped;
1044 where a reason for the skip is given, this is also printed.
1045 A line is also printed for each error encountered,
1046 describing the situtation;
1049 written to the standard error stream if (heurstically)
1054 .SS Test session lifecycle