.\" -*-nroff-*- .de VS .sp 1 .in +5 .nf .ft B .. .de VE .ft R .fi .in -5 .sp 1 .. .TH testrig 3 "5 June 1999" "Straylight/Edgeware" "mLib utilities library" .SH NAME testrig \- generic test rig .\" @test_run .SH SYNOPSIS .nf .B "#include " .BI "void test_run(int " argc ", char *" argv [], .BI " const test_chunk " chunk [], .BI " const char *" def ); .fi .SH DESCRIPTION The .B test_run function is intended to be called from the .B main function of a test rig program to check that a particular function or suite of functions are running properly. The arguments .I argc and .I argv should just be the arguments given to .BR main . The .I def argument gives the name of the default file of test vectors to read. This can be overridden at run-time by passing the program a .B \-f command-line option. The .I chunk argument is (the address of) an array of .I "chunk definitions" describing the layout of the test vector file. .SS "Test vector file syntax" Test vector files are mostly free-form. Comments begin with a hash .RB (` # ') and extend to the end of the line. Apart from that, newline characters are just considered to be whitespace. .PP Test vector files have the following syntax: .PP .I file ::= .RI [ chunk ...] .br .I chunk ::= .I name .B { .RI [ test-vector ...] .B } .br .I test-vector ::= .RI [ value ...] .B ; .PP Briefly in English: a test vector file is divided into chunks, each of which consists of a textual name and a brace-enclosed list of test vectors. Each test vector consists of a number of values terminated by a semicolon. .PP A value is either a sequence of .I "word characters" (alphanumerics and some other characters) or a string enclosed in quote marks (double or single). Quoted strings may contain newlines. In either type of value, a backslash escapes the following character. .SS "Chunk definitions" The caller must supply an array of one or more .IR "chunk definitions" . Each one describes the format of a named chunk: the number and type of the values required and the function to call in order to test the system against that test vector. The array is terminated by a chunk definition whose name field is a null pointer. .PP A chunk definition is described by the following structure: .VS typedef struct test_chunk { const char *name; /* Name of this chunk */ int (*test)(dstr dv[]); /* Test verification function */ test_type *f[TEST_FIELDMAX]; /* Field definitions */ } test_chunk; .VE The members of this structure are as follows: .TP .B "const char *name" The name of the chunk described by this chunk definition, or null if this is the termination marker. .TP .B "int (*test)(dstr dv[])" The test function. It is passed an array of dynamic strings, one for each field, and must return nonzero if the test succeeded or zero if the test failed. On success, the function should not write anything to stdout or stderr; on failure, a report of the test arguments should be emitted to stderr. .TP .B "test_type *f[TEST_FIELDMAX]" Definitions of the fields. This is an array of pointers to .I "field types" (see below), terminated by a null pointer. .PP When the test driver encounters a chunk it has a definition for, it reads test vectors one by one, translating each value according to the designated field type, and then passing the completed array of fields to the test function. .SS "Field types" A field type describes how a field is to be read and written. A field type is described by a structure: .VS typedef struct test_type { void (*cvt)(const char *buf, dstr *d); void (*dump)(dstr *d, FILE *fp); } test_type; .VE The .B cvt member is a function called to read an input string stored in .B buf and output internal-format data in the dynamic string .IR d . The testrig driver has already stripped of quotes and dealt with backslash escapes. The .B dump member is called to write the internal-format data in dynamic string .I d to the .B stdio stream .IR fp . .PP There are three predefined field types: .TP .B "type_string" The simplest type. The string contents is not interpreted at all. .TP .B "type_hex" The string is interpreted as binary data encoded as hexadecimal. .TP .B "type_int" The string is interpreted as a textual representation of an integer. The integer is written to the dynamic string, and can be read out again with the expression .VS *(int *)d.buf .VE which isn't pretty but does the job. .TP .B "type_long" As for .B type_int but reads and stores a .B long instead. .TP .B "type_ulong" As for .B type_long but reads and stores an .B "unsigned long" instead. .TP .B "type_uint32" As for .B type_int but reads and stores a .B uint32 (see .BR bits (3)) instead. .SH "SEE ALSO" .BR mLib (3). .SH "AUTHOR" Mark Wooding,