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_SYNTH ..."
109 .B "#define TVRF_ID ..."
110 .B "#define TVEC_ENDREGS ..."
112 .B "struct tvec_state;"
114 .B "struct tvec_env;"
115 .ta \w'\fBtypedef void tvec_testfn('u
116 .BI "typedef void tvec_testfn(const struct tvec_reg *" in ,
117 .BI " struct tvec_reg *" out ,
120 .B "struct tvec_test {"
121 .B " const char *name;"
122 .B " const struct tvec_regdef *regs;"
123 .B " const struct tvec_env *env;"
124 .B " tvec_testfn *fn;"
128 .B "struct tvec_config {"
129 .B " const struct tvec_test *const *tests;"
130 .B " unsigned nrout, nreg;"
133 .B "struct tvec_output;"
135 .ta \w'\fBvoid tvec_begin('u
136 .BI "void tvec_begin(struct tvec_state *" tv_out ,
137 .BI " const struct tvec_config *" config ,
138 .BI " struct tvec_output *" o );
139 .BI "int tvec_end(struct tvec_state *" tv );
140 .BI "int tvec_read(struct tvec_state *" tv ", const char *" infile ", FILE *" fp );
142 .B "#define TVHF_TTY ..."
143 .B "#define TVHF_COLOUR ..."
144 .ta \w'\fBstruct tvec_output *tvec_humanoutput('u
145 .BI "struct tvec_output *tvec_humanoutput(FILE *" fp ,
146 .BI " unsigned " f ", unsigned " m );
147 .BI "struct tvec_output *tvec_machineoutput(FILE *" fp );
148 .BI "struct tvec_output *tvec_tapoutput(FILE *" fp );
149 .BI "struct tvec_output *tvec_dfltoutput(FILE *" fp );
152 .B "struct tvec_amargs {"
154 .B " const char *name;"
158 .BI "struct tvec_output *tvec_amoutput(const struct tvec_amargs *" a );
161 .\"--------------------------------------------------------------------------
166 header file provides definitions and declarations
167 for the core of mLib's
168 .IR "test vector framework" .
170 The test vector framework is rather large and complicated,
171 so the documentation for it is split into multiple manual pages.
172 This one provides a conceptual overview
173 and describes the essentials for using it to build simple tests.
175 .SS Conceptual overview
178 runs a collection of tests
179 and reports on the outcome.
183 involves exercising some functionality
184 and checking that it behaves properly.
189 the functionality behaved properly.
192 the functionality did not behave properly.
194 .IR "expected failure" :
195 the functionality behaved as expected,
196 but the expected behaviour is known to be incorrect.
199 for some reason, the test couldn't be performed.
201 Tests are gathered together into
203 Each test group has a name.
204 Like a individual tests, test groups also have outcomes:
205 they can pass, fail, or be skipped.
206 A test group cannot experience expected failure.
208 A session may also encounter
210 e.g., as a result of malformed input
211 or failures reported by system facilities,
212 which prevent proper testing from proceeding.
213 The framework attempts to recover from errors,
214 so as to provide as useful a result as possible;
216 an error means that the test results are inconclusive.
218 A test session can either
219 be driven from data provided by an input file,
220 or it can be driven by the program alone.
221 The latter case is called
225 This manual page describes file-driven testing.
227 When it begins a session for file-directed testing,
228 the program provides a table of
229 .IR "test definitions" .
230 A test definition has a
233 .IR "test function" ,
235 .IR "test environment" ,
237 .IR "register definitions" .
238 Test environments are explained further below.
242 is a place which can store a single item of test data;
243 registers are the means
244 by which input test data is provided to a test function,
245 and by which a test function returns its results.
246 A test definition's register definitions
247 establish a collection of
250 Each active register has a
256 which are established by its register definition.
257 The register's name is used to refer to the register in the test data file,
258 and its index is used to refer to it
259 in the test function and test environments.
260 The register's type describes the acceptable values for the register,
261 and how they are to be compared,
262 read from the input file,
263 and dumped in diagnostic output.
264 New register types can be defined fairly easily: see
267 A register definition may describe an
272 input registers provide input data to the test function, while
273 output registers collect output data from the test function.
274 The data file provides values for both input and output registers:
275 the values for the input registers are passed to the test function;
276 the values for the output registers are
278 values against which the test function's outputs are to be checked.
280 The test function is called with two vectors of registers,
281 one containing input values for the test function to read
282 and also reference values,
283 and another for output values that the test function should write;
286 provided by the test environment.
287 The test function's task is to exercise the functionality to be tested,
288 providing it the input data from its input registers,
289 and collecting the output in its output registers.
290 It is the responsibility of the test environment or the framework
291 to compare the output register values against reference
292 provided in the input data.
294 The input file syntax is described in full below.
298 Comments begin with a semicolon character
300 and extend to the end of the line.
303 by headings in square brackets:
307 Each section contains a number of
309 separated by blank lines.
310 Each paragraph consists of one or more
320 When the framework encounters a section heading,
321 it finishes any test group currently in progress,
322 and searches for a test definition whose name matches the
324 name in the section heading.
326 it begins a new test group with the same name.
327 Each paragraph of assignments is used to provide
328 input and reference values
332 name in an assignment must match the name
333 of an active register or a
334 .I "special variable" ;
337 is stored in the named register or variable.
339 A register which has been assigned a value is said to be
343 By default, every active register must be live for a test to proceed;
344 but a register definition can mark its register as
348 An optional register need not be assigned a value explicitly;
349 instead, the register is left dead.
350 A may-be-unset register must be mentioned,
351 but a distinctive syntax
355 (with no colon or equals sign)
356 says that the register should be left dead.
357 Optional registers are suitable for cases where
358 there is an obvious default value
359 which would otherwise be mentioned frequently in input files.
360 May-be-unset registers are mostly useful as outputs,
361 where the output is not always set,
362 e.g., in error cases,
363 but where omitting a value in the usual case is likely a mistake.
365 A test environment fits in between
366 the framework and the test function.
367 It can establish hook functions which are called
368 at various points throughout a test group
369 (at the start and and, and before and after each test).
370 It can define special variables
371 which can be set from the input file using assignments.
372 And, finally, it can take on the responsibility
373 of running the test function.
374 The registers will have been set up already,
375 based on the assignments in the input file,
376 but the environment can modify them.
377 It must also check the test function's output
378 against the reference values,
379 though there are functions provided for doing this.
380 The environment can choose to run the test function once,
381 multiple times, or, indeed, not at all.
382 When it calls the test function, it can provide a context pointer,
383 with whatever additional information might be useful:
384 this usually involves coordination
385 between the environment and the test function.
386 It is the test environment's responsibility
387 to check the outputs returned by the test function
388 and to report on mismatches,
389 but there are functions provided by the framework
390 to do the heavy lifting.
392 The following are examples of what test environments can do.
394 It can fill in default values for optional dead registers.
395 For example, if a function returnns error codes,
396 then you can save reptition in the input file
397 by marking the error-code output register optional
398 and letting it default to the `success' value in a test environment.
400 It can run the test function mulitple times.
401 For example, a test of functions like
403 might run the test twice,
404 first with its operands as supplied by the input file,
405 and then again with the operands swapped
406 and the opposite expected result.
407 A test for bignum addition could verify commutativity
408 by checking both that
409 .IR x "\ + \ " y "\ =\ " z
411 .IR y "\ + \ " x "\ =\ " z \fR.
412 Similarly, a subtraction test could check both that
413 .IR x "\ \- \ " y "\ =\ " z
415 .IR y "\ \- \ " x "\ =\ \-" z \fR.
419 .BR tvec-timeout (3),
422 extensions all slot in as test environments,
423 with no extensions to the core API.
425 The framework includes a simple command-line front-end
430 function provides all of the necessary command-line
431 option and argument processing,
432 and handles the test session lifecycle,
433 given a pointer to the static tables
434 describing the supported test groups.
436 .SS Input file format
437 The file format is inspired by Windows
441 Comments begin with a semicolon
443 and continue to the end of the line;
444 a comment may be placed on a line by itself,
445 optionally preceded by whitespace;
446 or following other contents on a line.
448 Indentation and blank lines are significant;
449 trailing whitespace on a line is generally ignored.
450 Blank lines serve to separate groups of assignments into `paragraphs'
452 A line containing only a comment,
453 possibly preceded by whitespace,
455 and does not separate paragraphs.
456 An indented line is a
457 .IR "continuation line" ,
458 used to continue values over multiple lines.
460 A line beginning with an opening square bracket
463 .IR "section heading" ,
468 optionally followed by a comment.
471 may consist of any non-whitespace characters
472 other than the closing square bracket
474 Whitespace is permitted
475 (though not recommended)
476 between the brackets and the
480 must match the name of a test group
481 defined by the test configuration;
484 A section heading marks the start of a
486 which continues until the next section heading
487 or to the end of the file.
489 Each section consists of
493 by groups of one or more blank lines.
494 A line containing only a comment is
496 considered to be `blank' for the purposes of separating paragraphs.
497 There need not be blank lines
498 before the first paragraph in a section;
501 A paragraph consists of one or more
503 each of which begins with an unindented
505 followed by zero or more indented
506 .IR "continuation lines" .
508 An initial line begins with a
511 .IR "assignment operator" ;
512 the remaining contents, if any,
513 are determined by the name and operator.
514 A name is a sequence of non-whitespace characters
515 other than assignment operators, which are
522 There may be whitespace separating the name and operator.
525 .I "value assignment"
531 there is no difference in meaning between the two.
532 The operator is followed by optional whitespace and a
536 must match the name of a register or special variable
537 defined by the test group,
538 and the register or special variable definition determines
539 a register type for the assignment;
540 the syntax of the value is determined by the register type;
543 for the descriptions of the built-in types,
546 for how to define new register types.
549 may continue over multiple continuation lines,
550 each beginning with one or more whitespace characters.
551 The effect is to set the named register or special variable
552 to the specified value.
561 must match the name of a regsiter defined by the test group.
562 Only registers defined with the
566 flags (see below) can be unassigned;
567 special variables cannot be unassigned.
569 An error is reported if
570 the same register or special variable
571 is the subject of more than one assignment
573 or if there is no assignment for
574 a register defined by the test group
579 .SS Miscellaneous values
582 is a small union used
583 to pass a simple but opaque parameter
588 signed and unsigned integers
592 and a floating-point number
594 The pointer member is listed first,
595 because this is the most common (and general) case,
596 and the first member of a union
597 is the only member that can be initialized statically
598 in dialects (e.g., C89, C++14) which lack designated initializers.
600 There is an associated collection of constants,
606 which can be used to keep track of which member of a
609 These constants are currently not used by the framework.
614 is essentially a `slot' capable of holding a value.
615 Registers primarily occur as inputs and outputs for test functions,
616 but they also appear in other contexts.
618 The values that a particular register can hold
619 are determined by the register's
621 Register values are held in a
622 .BR "union tvec_regval" .
624 this union contains a number of useful C-level data types
625 corresponding to the provided register types;
626 see the synopsis above, and
629 More members can added by defining the macro
631 to the list of member declarations
635 A register value can hold resources,
636 such as allocated memory,
637 or even network connections or files.
638 A register value must be
643 when it is no longer required.
644 The life-cycle for register values is described in detail in
647 The state of a register is maintained in
648 .BR "struct tvec_reg" ,
649 which contains a flags word
652 .B "union tvec_regval"
655 At the start of the test session,
656 the framework allocates two vectors of
657 .B "struct tvec_reg" ,
666 specified in the test configuration.
669 vector must be at least as long as the
672 .BR nreg "\ \*(>=\ " nrout .
673 Within the framework,
674 registers are identified by their indices in these vectors.
676 .BI \fR0 "\ \*(<=\ " i "\ <\ " nrout
680 .BI nrout "\ \*(<=\ " i "\ <\ " nreg
683 other indices are invalid.
686 .I "register definition"
687 associates a name, type, and some flags, with a register index.
688 A register definitions is represented as a
689 .B "struct tvec_regdef"
690 structure, which has five members.
692 .B "const char *name"
694 This is used in input files to refer to the register.
696 .B "const struct tvec_regty *ty"
698 This can be the address one of the supplied
700 type structures described in
705 for how to implement new types.
708 The index of the register.
711 Flags defining additional special behaviour for the register.
712 The flags are described below.
714 .B "union tvec_misc arg"
715 An argument for the register type.
717 A test definition (see below) includes
718 a vector of register definitions.
719 The vector is terminated by an entry whose
721 member is a null pointer.
724 macro expands to a suitable static initializer.
726 The names and indices of register definitions
727 for a single test definition
729 A test definition need not include
730 a register definition for every register index;
731 the registers with associated definitions
735 those without a definition are said to be
737 Nothing useful can be done with inactive register indices:
738 inactive register don't even have an associated type.
740 The flags which can be set are as follows.
745 the register in input file paragraph
751 It is permitted for an input file paragraph
752 to have no assignment for the register.
753 It is also permitted for an input file paragraph
754 to unassign the register explicitly,
757 additionally implies the behaviour of
761 The register value constitutes part of
762 the `identity' of the test case.
765 uses the values of the registers whose
767 flag is set to label its performence results.
771 vector receives data from the input file.
772 When the framework processes an assignment,
775 in the register definitions:
777 it uses the associated index to locate the register.
778 In the case of a value assignment,
779 the framework invokes the register type's
781 function to read the value from the input file
785 and store it in the register.
786 If this is successful, then the framework sets the
790 flags on the register.
791 In the case of an unassignment,
792 the framework sets only the
795 Registers with indicess equal or greater than
797 provide input data to the test function.
798 Registers with indices less than
800 hold reference values:
801 a test function won't usually inspect these,
803 e.g., to determine an output buffer size.
805 Once the end of the paragraph is found,
806 the framework checks that
807 all of the necessary register have been assigned:
808 every register listed in the test group's register definitions
811 flag set, unless the definition sets the
814 It invokes the test function,
815 via the test environment, if one is defined.
816 See below for details on how the test function is invoked.
821 describes a test group.
822 Test definitions are represented as a
823 .B "struct tvec_test"
825 This has four members.
827 .B "const char *name"
829 This is used in input files to refer to the test group.
831 .B "const struct tvec_regdef *regs"
832 Pointer to the vector of register definitions.
833 The vector is terminated by an entry whose
837 .B "const struct tvec_env *env"
838 Pointer to the test environment for this test group.
839 Test environments are described in
841 Specific uses are discussed in
845 .BR tvec-timeout (3).
851 The signature for test functions is
854 .ta \w'\fBvoid \,\fItestfn\/\fB('u
855 .BI "void " testfn "(const struct tvec_reg *" in ,
856 .BI " struct tvec_rec_reg *" out ", void *" ctx );
863 arguments are the two register vectors discussed above,
864 the former holding the input and reference values,
865 and the latter for the outputs.
868 pointer is provided by the test environment.
869 If there is no test environment,
872 On entry to the test function,
873 all of the active registers are initialized,
880 registers corresponding to
881 live reference registers in the
883 additionally have their
887 Recall that an input-file paragraph can provide
888 a value assignment for a register,
891 A test function or test environment
892 can distinguish the three cases using the register flags:
894 A register which has been assigned a value
901 A register which has been explicitly unassigned has only the
904 Such a register's definition must have had either
910 A register which has not been assigned has neither flag set.
911 Such a register's definition must have had the
915 The test function will usually set the
917 registers corresponding to at least the live reference registers;
918 it may set additional active output registers
923 The caller will check the outputs
924 against the reference values from the input file.
927 occurs when a reference-value register is live and
928 either the corresponding output register is not live
929 or the output register value is not equal to the reference value
930 (as determined by the register type).
931 In the event of a mismatch,
932 the framework dumps the values of of the registers
933 and reports a failure.
937 passed a pointer to the
938 .B "struct tvec_state"
939 structure which is pretty much ubiquitous
940 in the test-vector framework interface.
941 A test function is not expected to `fail'
942 in the sense that it encounters a problem
943 that prevents it from performing the test.
944 Failure-prone setup can be performed by the test environment,
945 which can force a skip if necessary;
946 successfully acquired resources can be passed on
947 to the test function via the context pointer.
948 Errors encountered by the test function itself
949 should usually be reported by setting an output register.
950 If a test function really needs access to the test state,
951 an environment can arrange to pass it in via the context pointer.
953 .SS Test configurations
955 .IR "test configuration" ,
957 .B "struct tvec_config"
959 describes the global information required for a test session.
962 .B "const struct tvec_test *const *tests"
963 A pointer to a vector of pointers to test definitions,
964 terminated by a null pointer.
965 (Having pointers to the test definitions here,
966 rather than the definitions themselves,
967 allows the actual definitions to be kept alongside
968 the rest of the machinery required for the test group.)
971 The number of output registers.
974 The number of registers total.
976 .BR nreg "\ \-\ " nrout
981 .BR "struct tvec_reg" .
982 The fact that a test program can add
983 additional members to the
984 .B "union tvec_regval"
987 means that the true size of the union
988 was unknown when the framework
989 and application-agnostic extensions
991 They therefore need to learn the true size at runtime.
992 Since the main motivation is to be able to index the
998 .BR "struct tvec_reg" ,
1000 .B "union tvec_regval"
1002 that's of critical importance.
1005 The framework core does no output itself.
1006 Instead, all output is performed by an
1007 .IR "output driver" ,
1008 represented with the
1009 .B "struct tvec_output"
1013 for details about this structure
1014 and how to write new output drivers.
1015 This section describes the output drivers
1016 provided with the framework.
1024 and returns an output driver chosen in some unspecified way.
1027 refers to an `interactive device'
1028 then the `human' driver is chosen;
1029 otherwise, the `machine' driver is chosen.
1030 This behaviour may change in the future.
1031 If your program depends on a specific driver being chosen,
1032 then use it explicitly.
1034 The predefined drivers are as follows.
1035 .IP The `human' driver
1037 The `human' driver produces output expected to be useful to humans,
1040 unambiguous (I think)
1041 is probably rather difficult to parse.
1042 Moreover, the details of the output are subject to change.
1044 The `human' driver prints a line when a test or test group is skipped;
1045 where a reason for the skip is given, this is also printed.
1046 A line is also printed for each error encountered,
1047 describing the situtation;
1050 written to the standard error stream if (heurstically)
1055 .SS Test session lifecycle