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