1238104Sdes
2238104SdesCURSES TESTFRAME
3238104Sdes----------------
4238104Sdes
5238104Sdes1. Introduction
6238104Sdes
7238104SdesThe curses library is a complex piece of software and, often, changes
8238104Sdesmade to the library may introduce subtle bugs that are hidden by other
9238104Sdesactions so a visual check of the curses output may look correct in
10238104Sdessome circumstances and the bug only show itself after a certain
11238104Sdessequence of actions.  To assist with validating that changes made to
12238104Sdesthe curses library have no undesired effects an automated test is
13238104Sdesneeded to detect and highlight any changes in the curses application
14238104Sdesoutput stream.  The programmer can then analyse the output changes and
15238104Sdeseither correct a bug or update the automated test to accept the new
16238104Sdesoutput as valid.
17238104Sdes
18238104Sdes2. Architecture
19238104Sdes
20238104SdesThe curses testframe consists of two separate programs connected by a
21238104Sdesnumber of pipes and a pseudo-tty (pty).  The programs are called the
22238104Sdesdirector and the slave.  The director reads a configuration file of
23238104Sdestests to perform, passes these commands to the slave over a pipe and
24238104Sdesreads the pty for any output from the slave.  Data from the slave is
25238104Sdescompared against expected output held in a file and any differences
26238104Sdesare highlighted to the tester.  The slave is a curses application that
27238104Sdesis forked by the director on start up.  It reads commands from the
28238104Sdesdirector over a pipe, these commands are calls to curses routines
29238104Sdesalong with the parameters required for the call.  The slave takes the
30238104Sdesparameters and uses them as arguments for the requested curses routine
31238104Sdescall.  The return value from the curses routine is passed back to the
32238104Sdesdirector over another pipe, if the curses routine updates any passed
33238104Sdesby reference arguments then these are also passed back to the director
34238104Sdesfor analysis.
35238104Sdes
36238104Sdes3. Director
37238104Sdes
38238104SdesThe director has the following optional command line options:
39238104Sdes
40238104Sdes    -v	     	     enables verbose output to assist debugging
41238104Sdes    -s slave_path    the director will execute slave_path as the slave
42238104Sdes       		     process.  The default is ./slave
43238104Sdes    -t term	     Sets the TERM environment variable to term when
44238104Sdes       		     executing the slave.  The default is atf
45238104Sdes
46238104SdesThere is one mandatory command line parameter, that is a file name
47238104Sdesthat contains the test command file.  The test command file holds the
48238104Sdescalls required to exercise a particular curses routine and validate
49238104Sdesboth the return codes from the routines and the output from the
50238104Sdesslave.  The test language has a small number of commands, they are:
51238104Sdes
52238104Sdesassign:
53238104Sdes      Assign a value to a variable.  The syntax is:
54238104Sdes
55238104Sdes      	     assign var_name value
56238104Sdes
57238104Sdes      Where var_name is the name of the variable.  Variable names are
58238104Sdes      an arbitrary sequence of alphanumeric characters, the variable
59238104Sdes      name must start with an alphabetic character. Value is the value
60238104Sdes      to be assigned.  The value can either be a numeric or a string
61238104Sdes      type.  Variables are created on first use and will be
62238104Sdes      overwritten on each subsequent use.
63238104Sdes
64238104Sdescall, call2, call3, call4:
65238104Sdes      All these are used to call curses routines, the only difference
66238104Sdes      between then is the number of expected return values.  Call
67238104Sdes      expects one return value, call2 expects 2, call3 expects 3 and
68238104Sdes      call4 expects four.  Any parameters that are passed by reference
69238104Sdes      and updated by the call are treated like returns.  So, for
70238104Sdes      example, calling the function getyx() which has three
71238104Sdes      parameters, the window, a pointer to storage for y and a pointer
72238104Sdes      to storage for x would be called like this:
73238104Sdes
74238104Sdes      	 	 call3 OK 4 5 getyx $win1
75238104Sdes
76238104Sdes      Which calls getyx, the first (and possibly only) return is the
77238104Sdes      return status of the function call, in this case we expect "OK"
78238104Sdes      indicating that the call succeeded.  The next two returns are
79238104Sdes      the values of y and x respectively, the parameter $win1 is a
80238104Sdes      variable that was assigned by a previous call.  Any return can
81238104Sdes      be assigned to a variable by including the variable name in a
82238104Sdes      call return list.  Variables are referenced in a call parameter
83238104Sdes      list by prefixing the name with a $ character.  All returns are
84238104Sdes      validated against the expected values and an error raised if
85238104Sdes      there is a mismatch.  The only exception to this is when the
86238104Sdes      return is assigned to a variable.  Valid values for the returns
87238104Sdes      list are:
88238104Sdes
89238104Sdes      	  	  variable - assign the return to the given variable
90238104Sdes		             name.
91238104Sdes      	  	  numeric  - the value of the return must match the
92238104Sdes      	  	  	     number given.
93238104Sdes		  string   - an arbitrary sequence of characters
94238104Sdes      	  	  	     enclosed in double quotes.
95238104Sdes		  ERR      - expect an ERR return
96238104Sdes		  OK	   - expect an OK return
97238104Sdes		  NULL	   - expect a NULL pointer return
98238104Sdes		  NON_NULL - expect a pointer that is not NULL valued
99238104Sdes
100238104Sdes      There is one special parameter that can be passed to a call,
101238104Sdes      that is the label STDSCR.  This parameter will be substituted by
102238104Sdes      the value of stdscr when the function call is made.
103238104Sdes
104238104Sdescheck:
105238104Sdes      Validate the value of a variable.  This allows a variable to be
106238104Sdes      checked for an expected return after it has been assigned in a
107238104Sdes      previous call.  The syntax is:
108238104Sdes
109238104Sdes      	       check var_name expected_result
110238104Sdes
111238104Sdes      Where var_name is a variable previously assigned and
112238104Sdes      expected_result is one of the valid return values listed in the
113238104Sdes      above call section.
114238104Sdes
115238104Sdescompare:
116238104Sdes      Compares the output stream from the slave against the contents
117238104Sdes      of a file that contains the expected
118238104Sdes      output.  The syntax is:
119238104Sdes
120238104Sdes      	       compare filename
121238104Sdes
122238104Sdes      Where filename is the name of the file containing the expected
123238104Sdes      output.  The file can either be an absolute path or relative
124238104Sdes      path.  In the latter case the value of the environment variable
125238104Sdes      CHECK_PATH will be prepended to the argument to provide the path
126238104Sdes      to the file.  The contents of this file will be compared byte by
127238104Sdes      byte against the output from the slave, any differences in the
128238104Sdes      output will be flagged.  If the director is not in verbose mode
129238104Sdes      then the first mismatch in the byte stream will cause the
130238104Sdes      director to exit.
131238104Sdes
132238104Sdescomparend:
133238104Sdes      Performs the same function as the above compare except that
134238104Sdes      excess output from the slave is not discarded if there is more
135238104Sdes      data from the slave than there is in the check file.  This
136238104Sdes      allows chaining of multiple check files.
137238104Sdes
138238104Sdesdelay:
139238104Sdes      Defines an inter-character delay to be inserted between
140238104Sdes      characters being fed into the input of the slave.  The syntax
141238104Sdes      is:
142238104Sdes
143238104Sdes		delay time
144238104Sdes
145238104Sdes      Where time is the amount of time to delay in milliseconds.
146238104Sdes
147238104Sdesinclude:
148238104Sdes      Include the contents of another test file, the parser will
149238104Sdes      suspend reading the current file and read commands from the
150238104Sdes      include file until the end of file of the include file is
151238104Sdes      reached at which point it will continue reading the original
152238104Sdes      file.  Include files may be nested.  The syntax is:
153238104Sdes
154238104Sdes      	     	include filename
155238104Sdes
156238104Sdes      Where filename is the name of the file to include.  If the
157238104Sdes      filename is not an absolute path then the contents of the
158238104Sdes      environment variable INCLUDE_PATH are prepended to the file
159238104Sdes      name.
160238104Sdes
161238104Sdesinput:
162238104Sdes      Defines a string of characters that will be fed to the slave
163238104Sdes      when a call requires input.  Any unused input will be discarded
164238104Sdes      after the call that required the input is called.  The syntax
165238104Sdes      is:
166238104Sdes
167238104Sdes		input "string to pass"
168238104Sdes
169238104Sdesnoinput:
170238104Sdes      Normally the director will error if an input function is called
171238104Sdes      without input being previously defined, this is to prevent input
172238104Sdes      functions causing the test to hang waiting for input that never
173238104Sdes      comes.  If it is known that there is pending input for the slave
174238104Sdes      then the noinput keyword can be used to flag that the input
175238104Sdes      function has data available for it to read.  The noinput command
176238104Sdes      only applies to the next function call then behaviour reverts to
177238104Sdes      the default.
178238104Sdes
179238104SdesThe testframe can define different types of strings, the type of string
180238104Sdesdepends on the type of enclosing quotes.  A null terminated string is
181238104Sdesindicated by enclosing double (") quotes.  A byte string, one that is
182238104Sdesnot null terminated and may contain the nul character within it is
183238104Sdesindicated by enclosing single (') quotes.  A string of chtype
184238104Sdescharacter which are a combined attribute and character value is
185238104Sdesindicated by enclosing backticks (`), for this type of string pairs of
186238104Sdesbytes between the backticks are converted to an array of chtype, the
187238104Sdesfirst byte is the attribute and the second is the character.
188238104Sdes
189238104SdesAll strings defined will have a simple set of character substitutions
190238104Sdesperformed on them when they are parsed.  This allows the tester to
191238104Sdesembed some control characters into the string.  Valid substitutions
192238104Sdesare:
193238104Sdes
194238104Sdes	\e	escape
195238104Sdes	\n	new line
196238104Sdes	\r	carriage return
197238104Sdes	\t	tab
198238104Sdes	\\	\ character
199238104Sdes	\nnn	Where nnn is three octal digits, the character
200238104Sdes		represented by the octal number will be inserted into
201238104Sdes		the string.
202238104Sdes
203238104SdesAny other invalid conversions will have the \ stripped and the
204238104Sdessubsequent characters inserted into the string.
205238104Sdes
206238104SdesIntegers may be specified by either a plain numeric (e.g. 12345) or by
207238104Sdeshexadecimal notation by prefixing the number with 0x (e.g. 0x3039).
208238104SdesInternally, no distinction is made between the two formats and they
209238104Sdescan be freely intermixed.
210238104Sdes
211238104SdesIntegers and variables containing integers can have operations
212238104Sdesperformed on them.  Currently only bitwise ORing numbers together is
213238104Sdessupported.  This can be done by separating a list of integers and
214238104Sdesvariables with the pipe (|) symbol and enclosing the entire list in
215238104Sdesround brackets "()" like this:
216238104Sdes
217238104Sdes      ( $var1 | 0x0100 | $var2 | 512 )
218238104Sdes
219238104SdesVariables and integer constants may be freely intermixed.  The result
220238104Sdesof the operation can either be used as an argument for a call or can
221238104Sdesbe used as an expected result for a call.
222238104Sdes
223238104SdesIn addition to all the curses calls being supported by the slave,
224238104Sdesthere is one more special call called "drain".  This call repeatedly
225238104Sdescalled getch() until there are no more characters in stdin.  The call
226238104Sdesassumes that the curses input is either in no delay or timed input
227238104Sdesmode otherwise the test will time out and fail.  This call can be used
228238104Sdesto clear any pending input when testing testing a timed read to
229238104Sdesprevent the input being used in a later test.
230238104Sdes
231238104Sdes4. Slave
232238104Sdes
233238104SdesThe user has no direct interaction with the slave process.  The slave
234238104Sdesis forked off by the director communicates to the director over a set
235238104Sdesof pipes and a pseudo-tty connected to its standard i/o file
236238104Sdesdescriptors.  The slave executes the passed curses calls and passes
237238104Sdesback return values to the director.  The slave automatically calls
238238104Sdesinitscr() on start up.
239238104Sdes
240238104Sdes
241238104Sdes
242238104Sdes