111be35a1SLionel Sambuc 211be35a1SLionel SambucCURSES TESTFRAME 311be35a1SLionel Sambuc---------------- 411be35a1SLionel Sambuc 511be35a1SLionel Sambuc1. Introduction 611be35a1SLionel Sambuc 711be35a1SLionel SambucThe curses library is a complex piece of software and, often, changes 811be35a1SLionel Sambucmade to the library may introduce subtle bugs that are hidden by other 911be35a1SLionel Sambucactions so a visual check of the curses output may look correct in 1011be35a1SLionel Sambucsome circumstances and the bug only show itself after a certain 1111be35a1SLionel Sambucsequence of actions. To assist with validating that changes made to 1211be35a1SLionel Sambucthe curses library have no undesired effects an automated test is 1311be35a1SLionel Sambucneeded to detect and highlight any changes in the curses application 1411be35a1SLionel Sambucoutput stream. The programmer can then analyse the output changes and 1511be35a1SLionel Sambuceither correct a bug or update the automated test to accept the new 1611be35a1SLionel Sambucoutput as valid. 1711be35a1SLionel Sambuc 1811be35a1SLionel Sambuc2. Architecture 1911be35a1SLionel Sambuc 2011be35a1SLionel SambucThe curses testframe consists of two separate programs connected by a 2111be35a1SLionel Sambucnumber of pipes and a pseudo-tty (pty). The programs are called the 2211be35a1SLionel Sambucdirector and the slave. The director reads a configuration file of 2311be35a1SLionel Sambuctests to perform, passes these commands to the slave over a pipe and 2411be35a1SLionel Sambucreads the pty for any output from the slave. Data from the slave is 2511be35a1SLionel Sambuccompared against expected output held in a file and any differences 2611be35a1SLionel Sambucare highlighted to the tester. The slave is a curses application that 2711be35a1SLionel Sambucis forked by the director on start up. It reads commands from the 2811be35a1SLionel Sambucdirector over a pipe, these commands are calls to curses routines 2911be35a1SLionel Sambucalong with the parameters required for the call. The slave takes the 3011be35a1SLionel Sambucparameters and uses them as arguments for the requested curses routine 3111be35a1SLionel Sambuccall. The return value from the curses routine is passed back to the 3211be35a1SLionel Sambucdirector over another pipe, if the curses routine updates any passed 3311be35a1SLionel Sambucby reference arguments then these are also passed back to the director 3411be35a1SLionel Sambucfor analysis. 3511be35a1SLionel Sambuc 3611be35a1SLionel Sambuc3. Director 3711be35a1SLionel Sambuc 3811be35a1SLionel SambucThe director has the following optional command line options: 3911be35a1SLionel Sambuc 4011be35a1SLionel Sambuc -v enables verbose output to assist debugging 4111be35a1SLionel Sambuc -s slave_path the director will execute slave_path as the slave 4211be35a1SLionel Sambuc process. The default is ./slave 4311be35a1SLionel Sambuc -t term Sets the TERM environment variable to term when 4411be35a1SLionel Sambuc executing the slave. The default is atf 4511be35a1SLionel Sambuc 4611be35a1SLionel SambucThere is one mandatory command line parameter, that is a file name 4711be35a1SLionel Sambucthat contains the test command file. The test command file holds the 4811be35a1SLionel Sambuccalls required to exercise a particular curses routine and validate 4911be35a1SLionel Sambucboth the return codes from the routines and the output from the 5011be35a1SLionel Sambucslave. The test language has a small number of commands, they are: 5111be35a1SLionel Sambuc 5211be35a1SLionel Sambucassign: 5311be35a1SLionel Sambuc Assign a value to a variable. The syntax is: 5411be35a1SLionel Sambuc 5511be35a1SLionel Sambuc assign var_name value 5611be35a1SLionel Sambuc 5711be35a1SLionel Sambuc Where var_name is the name of the variable. Variable names are 5811be35a1SLionel Sambuc an arbitrary sequence of alphanumeric characters, the variable 5911be35a1SLionel Sambuc name must start with an alphabetic character. Value is the value 6011be35a1SLionel Sambuc to be assigned. The value can either be a numeric or a string 6111be35a1SLionel Sambuc type. Variables are created on first use and will be 6211be35a1SLionel Sambuc overwritten on each subsequent use. 6311be35a1SLionel Sambuc 6411be35a1SLionel Sambuccall, call2, call3, call4: 6511be35a1SLionel Sambuc All these are used to call curses routines, the only difference 6611be35a1SLionel Sambuc between then is the number of expected return values. Call 6711be35a1SLionel Sambuc expects one return value, call2 expects 2, call3 expects 3 and 6811be35a1SLionel Sambuc call4 expects four. Any parameters that are passed by reference 6911be35a1SLionel Sambuc and updated by the call are treated like returns. So, for 7011be35a1SLionel Sambuc example, calling the function getyx() which has three 7111be35a1SLionel Sambuc parameters, the window, a pointer to storage for y and a pointer 7211be35a1SLionel Sambuc to storage for x would be called like this: 7311be35a1SLionel Sambuc 7411be35a1SLionel Sambuc call3 OK 4 5 getyx $win1 7511be35a1SLionel Sambuc 7611be35a1SLionel Sambuc Which calls getyx, the first (and possibly only) return is the 7711be35a1SLionel Sambuc return status of the function call, in this case we expect "OK" 7811be35a1SLionel Sambuc indicating that the call succeeded. The next two returns are 7911be35a1SLionel Sambuc the values of y and x respectively, the parameter $win1 is a 8011be35a1SLionel Sambuc variable that was assigned by a previous call. Any return can 8111be35a1SLionel Sambuc be assigned to a variable by including the variable name in a 8211be35a1SLionel Sambuc call return list. Variables are referenced in a call parameter 8311be35a1SLionel Sambuc list by prefixing the name with a $ character. All returns are 8411be35a1SLionel Sambuc validated against the expected values and an error raised if 8511be35a1SLionel Sambuc there is a mismatch. The only exception to this is when the 8611be35a1SLionel Sambuc return is assigned to a variable. Valid values for the returns 8711be35a1SLionel Sambuc list are: 8811be35a1SLionel Sambuc 8911be35a1SLionel Sambuc variable - assign the return to the given variable 9011be35a1SLionel Sambuc name. 9111be35a1SLionel Sambuc numeric - the value of the return must match the 9211be35a1SLionel Sambuc number given. 9311be35a1SLionel Sambuc string - an arbitrary sequence of characters 9411be35a1SLionel Sambuc enclosed in double quotes. 9511be35a1SLionel Sambuc ERR - expect an ERR return 9611be35a1SLionel Sambuc OK - expect an OK return 9711be35a1SLionel Sambuc NULL - expect a NULL pointer return 9811be35a1SLionel Sambuc NON_NULL - expect a pointer that is not NULL valued 9911be35a1SLionel Sambuc 10011be35a1SLionel Sambuc There is one special parameter that can be passed to a call, 10111be35a1SLionel Sambuc that is the label STDSCR. This parameter will be substituted by 10211be35a1SLionel Sambuc the value of stdscr when the function call is made. 10311be35a1SLionel Sambuc 10411be35a1SLionel Sambuccheck: 10511be35a1SLionel Sambuc Validate the value of a variable. This allows a variable to be 10611be35a1SLionel Sambuc checked for an expected return after it has been assigned in a 10711be35a1SLionel Sambuc previous call. The syntax is: 10811be35a1SLionel Sambuc 10911be35a1SLionel Sambuc check var_name expected_result 11011be35a1SLionel Sambuc 11111be35a1SLionel Sambuc Where var_name is a variable previously assigned and 11211be35a1SLionel Sambuc expected_result is one of the valid return values listed in the 11311be35a1SLionel Sambuc above call section. 11411be35a1SLionel Sambuc 11511be35a1SLionel Sambuccompare: 11611be35a1SLionel Sambuc Compares the output stream from the slave against the contents 11711be35a1SLionel Sambuc of a file that contains the expected 11811be35a1SLionel Sambuc output. The syntax is: 11911be35a1SLionel Sambuc 12011be35a1SLionel Sambuc compare filename 12111be35a1SLionel Sambuc 12211be35a1SLionel Sambuc Where filename is the name of the file containing the expected 12311be35a1SLionel Sambuc output. The file can either be an absolute path or relative 12411be35a1SLionel Sambuc path. In the latter case the value of the environment variable 12511be35a1SLionel Sambuc CHECK_PATH will be prepended to the argument to provide the path 12611be35a1SLionel Sambuc to the file. The contents of this file will be compared byte by 12711be35a1SLionel Sambuc byte against the output from the slave, any differences in the 12811be35a1SLionel Sambuc output will be flagged. If the director is not in verbose mode 12911be35a1SLionel Sambuc then the first mismatch in the byte stream will cause the 13011be35a1SLionel Sambuc director to exit. 13111be35a1SLionel Sambuc 13211be35a1SLionel Sambuccomparend: 13311be35a1SLionel Sambuc Performs the same function as the above compare except that 13411be35a1SLionel Sambuc excess output from the slave is not discarded if there is more 13511be35a1SLionel Sambuc data from the slave than there is in the check file. This 13611be35a1SLionel Sambuc allows chaining of multiple check files. 13711be35a1SLionel Sambuc 13811be35a1SLionel Sambucdelay: 13911be35a1SLionel Sambuc Defines an inter-character delay to be inserted between 14011be35a1SLionel Sambuc characters being fed into the input of the slave. The syntax 14111be35a1SLionel Sambuc is: 14211be35a1SLionel Sambuc 14311be35a1SLionel Sambuc delay time 14411be35a1SLionel Sambuc 14511be35a1SLionel Sambuc Where time is the amount of time to delay in milliseconds. 14611be35a1SLionel Sambuc 14711be35a1SLionel Sambucinclude: 14811be35a1SLionel Sambuc Include the contents of another test file, the parser will 14911be35a1SLionel Sambuc suspend reading the current file and read commands from the 15011be35a1SLionel Sambuc include file until the end of file of the include file is 15111be35a1SLionel Sambuc reached at which point it will continue reading the original 15211be35a1SLionel Sambuc file. Include files may be nested. The syntax is: 15311be35a1SLionel Sambuc 15411be35a1SLionel Sambuc include filename 15511be35a1SLionel Sambuc 15611be35a1SLionel Sambuc Where filename is the name of the file to include. If the 15711be35a1SLionel Sambuc filename is not an absolute path then the contents of the 15811be35a1SLionel Sambuc environment variable INCLUDE_PATH are prepended to the file 15911be35a1SLionel Sambuc name. 16011be35a1SLionel Sambuc 16111be35a1SLionel Sambucinput: 16211be35a1SLionel Sambuc Defines a string of characters that will be fed to the slave 16311be35a1SLionel Sambuc when a call requires input. Any unused input will be discarded 16411be35a1SLionel Sambuc after the call that required the input is called. The syntax 16511be35a1SLionel Sambuc is: 16611be35a1SLionel Sambuc 16711be35a1SLionel Sambuc input "string to pass" 16811be35a1SLionel Sambuc 16911be35a1SLionel Sambucnoinput: 17011be35a1SLionel Sambuc Normally the director will error if an input function is called 17111be35a1SLionel Sambuc without input being previously defined, this is to prevent input 17211be35a1SLionel Sambuc functions causing the test to hang waiting for input that never 17311be35a1SLionel Sambuc comes. If it is known that there is pending input for the slave 17411be35a1SLionel Sambuc then the noinput keyword can be used to flag that the input 17511be35a1SLionel Sambuc function has data available for it to read. The noinput command 17611be35a1SLionel Sambuc only applies to the next function call then behaviour reverts to 17711be35a1SLionel Sambuc the default. 17811be35a1SLionel Sambuc 17911be35a1SLionel SambucThe testframe can define different types of strings, the type of string 18011be35a1SLionel Sambucdepends on the type of enclosing quotes. A null terminated string is 18111be35a1SLionel Sambucindicated by enclosing double (") quotes. A byte string, one that is 18211be35a1SLionel Sambucnot null terminated and may contain the nul character within it is 18311be35a1SLionel Sambucindicated by enclosing single (') quotes. A string of chtype 18411be35a1SLionel Sambuccharacter which are a combined attribute and character value is 18511be35a1SLionel Sambucindicated by enclosing backticks (`), for this type of string pairs of 18611be35a1SLionel Sambucbytes between the backticks are converted to an array of chtype, the 18711be35a1SLionel Sambucfirst byte is the attribute and the second is the character. 18811be35a1SLionel Sambuc 18911be35a1SLionel SambucAll strings defined will have a simple set of character substitutions 19011be35a1SLionel Sambucperformed on them when they are parsed. This allows the tester to 19111be35a1SLionel Sambucembed some control characters into the string. Valid substitutions 19211be35a1SLionel Sambucare: 19311be35a1SLionel Sambuc 19411be35a1SLionel Sambuc \e escape 19511be35a1SLionel Sambuc \n new line 196*84d9c625SLionel Sambuc \r carriage return 19711be35a1SLionel Sambuc \t tab 19811be35a1SLionel Sambuc \\ \ character 19911be35a1SLionel Sambuc \nnn Where nnn is three octal digits, the character 20011be35a1SLionel Sambuc represented by the octal number will be inserted into 20111be35a1SLionel Sambuc the string. 20211be35a1SLionel Sambuc 20311be35a1SLionel SambucAny other invalid conversions will have the \ stripped and the 20411be35a1SLionel Sambucsubsequent characters inserted into the string. 20511be35a1SLionel Sambuc 20611be35a1SLionel SambucIntegers may be specified by either a plain numeric (e.g. 12345) or by 20711be35a1SLionel Sambuchexadecimal notation by prefixing the number with 0x (e.g. 0x3039). 20811be35a1SLionel SambucInternally, no distinction is made between the two formats and they 20911be35a1SLionel Sambuccan be freely intermixed. 21011be35a1SLionel Sambuc 21111be35a1SLionel SambucIntegers and variables containing integers can have operations 21211be35a1SLionel Sambucperformed on them. Currently only bitwise ORing numbers together is 21311be35a1SLionel Sambucsupported. This can be done by separating a list of integers and 21411be35a1SLionel Sambucvariables with the pipe (|) symbol and enclosing the entire list in 21511be35a1SLionel Sambucround brackets "()" like this: 21611be35a1SLionel Sambuc 21711be35a1SLionel Sambuc ( $var1 | 0x0100 | $var2 | 512 ) 21811be35a1SLionel Sambuc 21911be35a1SLionel SambucVariables and integer constants may be freely intermixed. The result 22011be35a1SLionel Sambucof the operation can either be used as an argument for a call or can 22111be35a1SLionel Sambucbe used as an expected result for a call. 22211be35a1SLionel Sambuc 22311be35a1SLionel SambucIn addition to all the curses calls being supported by the slave, 22411be35a1SLionel Sambucthere is one more special call called "drain". This call repeatedly 22511be35a1SLionel Sambuccalled getch() until there are no more characters in stdin. The call 22611be35a1SLionel Sambucassumes that the curses input is either in no delay or timed input 22711be35a1SLionel Sambucmode otherwise the test will time out and fail. This call can be used 22811be35a1SLionel Sambucto clear any pending input when testing testing a timed read to 22911be35a1SLionel Sambucprevent the input being used in a later test. 23011be35a1SLionel Sambuc 23111be35a1SLionel Sambuc4. Slave 23211be35a1SLionel Sambuc 23311be35a1SLionel SambucThe user has no direct interaction with the slave process. The slave 23411be35a1SLionel Sambucis forked off by the director communicates to the director over a set 23511be35a1SLionel Sambucof pipes and a pseudo-tty connected to its standard i/o file 23611be35a1SLionel Sambucdescriptors. The slave executes the passed curses calls and passes 23711be35a1SLionel Sambucback return values to the director. The slave automatically calls 23811be35a1SLionel Sambucinitscr() on start up. 23911be35a1SLionel Sambuc 24011be35a1SLionel Sambuc 24111be35a1SLionel Sambuc 242