You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



Regress Tool Specification

Newsgroup: mozilla.dev.tech.crypto
Technical contact: Bob Relyea
Yell at the manager: Bob Lord


Last updated: 6/30/1998

Contents


Overview

Regress is a test case execution and reporting tool that operates as follows. It accepts a specification file [that is intended to be platform and location independent] that defines a number of test cases (programs) and a description for each case.  Regress runs the series of programs, in the order of the specfile, and captures into an html output file a table of results:  the date/time of run, program run, and results (PASS or FAIL).   Regress also generates a summary output file suitable for collecting overall results from a number of test suites.  Regress generates results that are utilized by reporter.  Additionally, tools like replacer generate test suites that integrate well with regress.

NOTE: When specifying directories in this document, it is not necessary to worry about the "/" vs. the "\" conventions. The regression tool will figure out which slash to use.


Command line interface

regress specfile=filename [htmldir=dir] [progdir=dir] [lang=java|c] [style=table|javascript] [jvm=<java interpreter>] [classpath=<java CLASSPATH setting>] [args=<global arguments>] [debug]

[commands in brackets are optional]
 
 
Command line option Explanation
specfile specifies the input specfile (defined below) that regress uses to find out what to execute. The path to the file can be relative or absolute.
debug If debug is in the command line, information will be output to STDOUT so developers of regress can see what is going on. 
progdir specifies the base directory where all the executables are. It could be a relative or absolute path. 
htmldir specifies the base directory where all the html results and reporter specs are output to. It could be a relative or absolute path. 
lang=[java|c] specifies whether regress is to expect a java class or c executable. By specifying the option "lang=java" at the command line will put regress in JAVA_MODE, similarly "lang=c" places regress in C_MODE. 
Again, command line options override specfile setting. 
style=[table|javascript] specifies the display style of the output HTML, whether it be the table format or Java Script format.   If not specified, the default is the javascript format (unless, otherwise specified in the regress specfile)
jvm=<java interpreter path>  specifies the path of the java virtual machines used to interpret java .class files.   (This option overrides the jvm specified in the specfile).   If lang=c then the jvm field is ignored.
classpath=<java CLASSPATH setting> This option allows the added flexibility of letting the user specify the java environment variable CLASSPATH for running their testsuites.   This option will overide a classpath setting in the [General] section of the regress specfile.  If classpath is not set both at the command line or in the specfile, then the CLASSPATH of the user's environment will be used.  (If environment CLASSPATH is not set, then, the default "." (current directory) is used.)
args=<global arguments> This option allows on the fly specification of globalArgs.  This field overrides the globalArgs field in the specfile. (This feature may be currently only available on Solaris 5.5.1 versions)




Regress Return Codes
 
 
Error Codes Description
0 All Tests are PASS or Known failures
1 One or more tests FAIL or are MALFORMED
2 One or more tests returned the predefined abortCode (see abortCode definition below)
3 Did not include specfile= directive on command line
4 Specfile is malformed or does not exist
5 No [General] section in specfile 
6 No mut= line in [General] section
7 No mutversion= line in [General] section
8 No htmlout= line in [General] section
9 No reporterSpec= line in [General] section
10 No mainClassName= line in [General] while in Java mode
11 Usage message displayed; Undefined command line options used.
Tests should use exit codes from the range of 1 to 255 due to Unix limitation on transferred exit codes. 256 exit code is reserved for test crash.


Regress Specfile

It is a convention to use a .reg extension for any regress specfiles. This is not checked, but is for purely readability purposes. Please check the convention document if you don't know what extension to put on your files for other people's sake.

The following is a specification of the regress tools Test Case Specification file:
 
 
 
Specification File Element Description of Element
[General] Starts the General information block that describes the collection of unit tests in this directory.
mut=description Defines a description for the module under test (e.g., ns/security/lib/crypto module could be described as "Security Library: Cryptographic Module (lib/crypto)".
mutversion=versionstring Defines a version string for the collection of tests. It is assumed that each test will execute against this higher level versionstring version, and that the results will be reported against this version string.
htmlout=<filename> Defines the location and filename relative to htmldir of the html test output that is generated by the regress tool. If the <filename> is NOW, then a yyyymmdd.htm string will be substituted for the filename (eg. 19970801). This has to be a relative path to the htmldir specified above. If htmldir is not set, it is automatically default to "."
reporterSpec=<filename> Defines the location and filename of the specfile that is generated by the regress tool and read in by the reporter tool). See specification of reporter specfile. If the <filename> is NOW, then a yyyymmdd.rpt string will be substituted for the filename (eg. 19970801). This has to be a relative path to the htmldir specified above. If htmldir is not set, it is automatically default to "." 
program=<filename> Program name placed in general section is used with single source testing method only, which also requires to have test IDs in the individual test sections. For additional information see replacer.
globalArgs=<arg list string> Defines a list of arguments tacked on to all of the programs when the regression suite is run (this will simply concatenate the <program><space><globalArgs> together). This header is optional.
bugQueryUrl=<URL with metavariable> Defines a URL that has a metavariable $[BUG-NUMBER] that is replaced by the bug number when a test is a known failure. This header is optional.
firstKnownFailure=<number between 0 and 256> Specifies the first return code which regress should consider as a known failure.   When specified with first Error code, defines a range of executable return codes that are considered known failures. When not specified or incorrectly specified (i.e. bigger than firstErrorCode) the default value is 0.
firstErrorCode=<number between 0 and 256> Defines the upper bound of known failure codes. [Hence known failure codes are from 
firstKnownFailure to firstErrorCode - 1].    If firstErrorCode is smaller than firstKnownFailure or otherwise undefined, then default value of 0 is used.
timeout=<an positive integer| FOREVER> Specifies the global timeout for the program.  The timeout value can be a number from 1 to 2^32 -1, which will be in the units of seconds.  By setting timeout to FOREVER means that there won't be a timeout.   (regress will let the process run literally forever).   The global timeout can be overridden by the timeout attribute for each test.  If neither the global timeout or testspecific timeout is given, the default value of 1000 seconds is used.  [A Note of warning: a timeout of 0 is interpreted the same way as not setting this field, so the default 1000 seconds would be used in that case.]
localExecutable=[TRUE|FALSE] Normally, if progdir is not specified at the command line, regress assumes that the executable is in the currently working directory; Regress will pre-append to the executable: "./<executable>".   If localExecutable = FALSE, this default behavior is turned off, in which case, regress will prepend nothing in front of the executable (unless progdir is specified).   This option is useful since it allows one to manipulate the environment PATH variable to select the executable to test. 
By default localExecutable is TRUE.
autoAppendExtension=[TRUE|FALSE] By default, regress will append the extension .exe to all executables in the Windows/PC versions.  By specfying this field as FALSE will turn off this behavior.  By default autoAppendExtension is set to TRUE.
abortCode=<number between 0 and 256> If a test returns a code identical to the abortCode as defined here.  That particular test will be marked as "FAIL: ABORT".  And regress will return 2 as its return code (after finish running all the remaining tests).    If abortCode is not defined, the default value of 255 will be used.
style=[table|javascript] Specifies whether the output report HTML will be in table format or JavaScript format.
language=[java|c] If language=java, puts Regress in JAVA_MODE, and hence regress expects a java class file. 
By default language=c if language is not specified.
mainClassName = <name of your class containing main() > Required if in JAVA_MODE.   mainClassName is used to qualify the names of injected arrays in single file mode, and during given as argument to the java interpreter as in: 
<jvm>  <packageName>.<mainClassName>
jvm = <path to your Java Interpreter>  Used to specify which java interpreter to use.  It's best that full path is specified.   If not specified, regress will use "java".
packageName=<package name from package declaration> Required if a package declaration appears in the source file.   Required by Regress to construct the test program command: 
<jvm> <packageName>.<mainClassName>
classpath=<java CLASSPATH setting> Required if the test suite uses a CLASSPATH different from that specified in the user environment.  If specified, regress will create a CLASSPATH environment variable in its test environment and clobber any previous settings.   If this field is not specified, then the classpath from the environment will be used.  If no environment CLASSPATH is set, then the  default working directory (progdir) will be used.
In JAVA_MODE, 
If Single Source Mode is specified 
 "program="  field in [General] is not necessary.
When Single Source Mode is TRUE (on).  The user no longer need to specify 
the program field if JAVA_MODE is on.    Regress will simple construct the program to run from the jvm, packageName, and mainClassName provided.   As a result, Regress will run: 
         <jvm> <packageName>.<mainClassName> <Args>
Test Header
[Test-X] Begins an information block for a specific test. The X value must be replaced with an integer >= 1. The following name value pairs are related to each [Test-X] block.
program=<filename> This is the relative path (relative to the progdir) to the executable. This is the program to execute that calls PR_ProcessExit or return and returns a 0 for success, or 1 for failure. If progdir is not set, progdir is defaulted to "." 
It is not necessary to add a ".exe" extension at the end of the program name when specifying a Windows / DOS executable. 
Program won’t be specified in this section when using single source testing method.
In JAVA_MODE  If Single Source Mode is NOT specified  (Multiple source mode) 
program =<test directory>
For each test specified, the user must set the program metavariable to the name of the directory in which the Java source code or (source Tree) resides.  (for a better explanation see Regress in Java Mode below)
testId=<test ID> testId  is used with single source testing method only. It is transferred to the test as a first argument.
testname=<description> This is the description of what the test program is testing. 
timeout=<positive integer|FOREVER> This is the timeout in seconds to run a test. If a test runs longer than the timeout, it is killed and returns fail. This field is optional.  If this field is not set, the global timeout specified in the timeout= field of the [General] section will be used.  The key word FOREVER will cause the test to be run without any timeout.  By default, if neither the local timeout nor global timeout is set, 1000 seconds will be used as the timeout limit.
bug=<positive integer> This is an optional field. This is set whenever there is a known test failure. The test will NOT be run when this field is set. 
include=<platforms> This is an optional field. This is set whenever a test is specific to a certain platform or group of platforms. The test will be run only on the platforms (separated by commas or whitespace) in the include list.Check the list for what string to use for your platform. If your platform is not on the list, check the output platform header in the output HTML to see the string you need to use. 

This field is case insensitive (eg. you can use solaris2.5 if you want). 

The test will result in a PASS if the platform is not in the include list (The test didn't really fail, it just wasn't run). 

Note: having both an include and exclude tag is invalid and will result in an error.
 
 

exclude=<platforms> This is an optional field. This is set whenever a test is not supposed to be run on a certain platform or group of platforms. The test will not be run on the platforms (separated by commas or whitespace) in the exclude list. Check the list for what string to use for your platform. If your platform is not on the list, check the output platform header in the output HTML to see the string you need to use. 

This field is case insensitive (eg. you can use solaris2.5 if you want). 

The test will result in a PASS if the platform is in the exclude list (The test didn't really fail, it just wasn't run). 

Note: having both an include and exclude tag is invalid and will result in an error.
 
 


Regress in Java Mode

When Regress is in Java Mode (by setting lang=java at the command line or language=java in the specfile).   Regress expects the following
fields to appear in the specfile under the [General Header]:
mainClassName, jvm, classpath, and packageName.
jvm, classpath, and packageName are optional.   jvm is set to a default of "java" if not specified any where.   And classpath inherits the environment CLASSPATH, if not specified anywhere.

The user is responsible for making sure that the directory tree in which the .class files are stored exist and the .class files themselves also exist.   Because regress do not read environmental variables, the value of classpath set in the specfile must be a real path not a variable.    However, if classpath is set at the command line, the argument can be a variable.
e.g.
A correct usage:

regress specfile=mytest.reg classpath=$CLASSPATH:/usr/bin

But
[General]
...
classpath=$CLASSPATH   #WRONG!
..

The classpath can be further appended for each test run.  This is accomplished by adding the attribute
program=<testdir> in each test heading.

[test-1]
program=t0
....

Regress will append the value set in the program field to the CLASSPATH it already has.

When regress runs, it will do the following:

setenv CLASSPATH <value set in classpath=>:<testdir>
<jvm> <fully qualified class name>   # i.e. combination of package name and mainClassName.

Following is an example that illustrates what processes must occur for regress to work in Java mode (multiple source mode).

Example:

A user has 5 tests (.java files).   These 5 tests sources are place in the following directories:

t1/foo/bar/t1.java
t2/foo/bar/t2.java
t3/foo/bar/t3.java
t4/foo/bar/t4.java
t5/foo/bar/t5.java

Each .java file has the same package declaration:
package foo.bar;
and has a mainClassName of "test"

After compilation the following 5 .class files were created:

t1/foo/bar/test.class
t2/foo/bar/test.class
t3/foo/bar/test.class
t4/foo/bar/test.class
t5/foo/bar/test.class

In order to run regress for the above example, the user must write a specfile that is something like the following:

[General]
...
language=java
mainClassName=test
packageName=foo.bar
jvm=/tools/ns/bin/java
# no classpath, inherit from environment
....

[Test-1]
program=t1
.... other fields

[Test-2]
program=t2
.... other fields

[Test-n]
program=<test directory n>
.... other fields

Regress takes the above specfile and runs each test in a manner equivalent to the following:

setenv CLASSPATH <$CLASSPATH>:t0     // or which ever test that is running
/tools/ns/bin/java foo.bar.test


Platform strings

The following is a specification of sample platform strings you can use for the include and exclude headers:

SOLARIS2.5
SOLARIS2.4
SOLARIS2.3
WINNT
HPUXB.10.10
OSFV4.0
AIX1
IRIX5.3
IRIX6.2




Individual Test Output

The following is a specification of what the return value should be for each Individual Test case executable.

Each of these test cases makes up one singular test within the overall regression test suite. The regression test suite is defined by the Test Specification File.
 
 
Output Description Format of Output
Test pass fail status indicator. The program must call PR_ProcessExit(0) if the test passes. If any other value is returned, that means that the test fails. 0   -- PASS 
non-zero value -- FAIL 
marked non-zero value(set using firstKnownFailure) -- FAIL -- KNOWN FAIL 
It is a convention during failures to use the current line number of the program or replacer template as the return value for easier debugging.

Note: If the Individual Test case requires known answers to benchmark the results of the execution against, then it is the responsibility of the individual test case to manage the creation / deletion of startup / shutdown known answers.


Regress Test Results Report

Table style
The following is a specification of the html output format for the regress tool in TABLE mode:
Section Description HTML format
Document Title

The title is generated from the mut= specifier. The version is generated from mutversion=. The date and time is relative to the beginning point of the execution of the regression test suite.
 
 

<HTML><HEAD><TITLE>mut description: Version: mutversion Platform: platform Run date mm/dd/yy</TITLE></HEAD><BODY>\n
H1 Header for the report. <H1>mut description: Version: mutversion Platform: platform Run date mm/dd/yy</H1><HR>\n
Table header <TABLE BORDER=1><TR>\n
<TD><B>Test Case Number</B></TD>\n
<TD><B>Program</B></TD>\n
<TD><B>Description of Test Case</B></TD>\n
<TD><B>Start date/time<B></TD>\n
<TD><B>End date/time<B></TD>\n
<TD><B>PASS/FAIL</B></TD>\n
</TR>\n
Table Detail

Open the output file defined by htmlout= specifier in the [General] section of the specification file. 

For each test case header [Test-X] (X >= 1) in the Test Specification file, 
 
 

    (1) Capture the date/time prior to execution (this is start date/time
    (2) Execute the program (program=filename) capturing the return code. If program runs past timeout, kill the program. 
    (3) Capture the date/time after execution (this is the end date/time)
    (4) Generate the HTML ouptut -- if the specfile is missing some headers, then the result is "MALFORMED". Otherwise, the result string is either PASS or FAIL. If the test returns a pass, the test row is greyed out. If the test fails, the result will be in red.
Notes: The <description> is associated with [Test-X] and is the description given after testname= in the specification block. 
<TR [if pass then BG COLOR="#C0C0C0">]\n
<TD><B>X</B></TD>\n
<TD>filename</TD>\n
<TD>description</TD>\n
<TD>mm/dd/yy hh:mm:ss</TD>\n
<TD>mm/dd/yy hh:mm:ss</TD>\n
<TD><B> 
PASS |
PASS : This test was excluded or not included for this platform |
<FONT COLOR="#FF0000"> FAIL: return code = errnum. </FONT> | 
<FONT COLOR="#FF0000"> FAIL: CreateProcess </FONT> | 
<FONT COLOR="#FF0000"> FAIL: WaitProcess </FONT> | 
<FONT COLOR="#FF0000"> FAIL: Known bug. Bug number = 51325 </FONT> | 
<FONT COLOR="#FF0000"> FAIL: Timeout after 10 seconds </FONT> | 
MALFORMED : include= and exclude= tags BOTH defined |
MALFORMED : program= not defined in [header] |
MALFORMED : testname= not defined in [header] |
MALFORMED : test number=header-part not valid positive integer |
MALFORMED : test number header invalid
</B></TD>\n
</TR>\n
Table trailer </TABLE>\n
Summary Line <TABLE> 
<TR><TD><B>Summary Results</B></TD><TD>Count</TD></TR> 
<TR><TD>Tests Failed</TD><TD><number failed></TD></TR> 
<TR><TD>Test Passed</TD><TD><number passed></TD></TR> 
<TR><TD>Known Failures</TD><TD><known failures></TD><TR> 
<TR><TD>Malformed Specification</TD><TD><number malformed></TD></TR> 
</TABLE> 
End of HTML </BODY></HTML>\n


Javascript Style

Overview
The strictly tabular format produced by Regress has the following disadvantages:
 
 

  • When entries get above 8000, the Browser will often crash due to difficulties in drawing the table for such a large number of entries.
  • When there are too many entries, it is difficult to go to a specific test and look at the results.
  • There is no mechanism in which to look at only fail entries or only pass entries given a page containing a mix of both types
The solution is to create an additional interface to the Regress output display -- Implement  an easy to use interface that uses JavaScript to dynamically page
through the data.

The new javascript format has a self contained paging mechanism and allows display of FAILS only or PASS only.   Buttons on the bottom of the page adds page up, page down, table top, table bottom, goto page functionalities.

Here is an example of the JavaScript output

The output is separated into 3 frames.   The top frame contains static information such as summary statistics, platform name, test name, and test description.
The center frame contains the paged result table.  Currently, the number of entries per page is set to 12.   But this can be changed by changing the javascript variable entriesPerPage in the source file genjs_template.html.  (see extra building instructions).  The bottom frame is basically a control panel that has the paging buttons.

Behavior
When viewing a page in FAIL only or PASS only mode.  The javascript is designed to find as many entries as possible that fit the PASS or FAIL category starting from the current entry number.  For example, in the case where we are viewing FAIL entries only, if the current entry is entry 47, and there are only 3 fail entries after 47, the javascript program will search forward until either it hits the beginning or 12 entries are found;  Then displaying all 12 or less entries found.



Reporter Specfile Output Format:
 
 
 
Specification File Element Description of Element
[Status] Is the only block in this specification file
mut=description Defines a description for the module under test (e.g., ns/security/lib/crypto module could be described as "Security Library: Cryptographic Module (lib/crypto)".
mutversion=versionstring Defines a version string for the collection of tests. It is assumed that each test will execute against this higher level versionstring version, and that the results will be reported against this versionstring.
platform=<string> Defines the platform the tests were run under
pass=<number> Number of tests that passed.
fail=<number> Number of tests that failed due to non-zero return codes, timeouts, OR any other abnormality when running the test.
knownFail=<number> Number of tests that were known to fail because a bug number was specified in its regress specfile. 
malformed=<number> Number of tests with bad headers (see regress specfile specifications).

Note: check the Reporter Spec for the latest reporter specification.

Implementation Notes for regress

  • The regress tool shall parse and generate the outputs described by the 3 input/output specifications listed above.
  • The regress tool can re-use HSA's varfile.h/varfile.c Variable File interface, but should first port this interface to use cross-platform (XP) calls instead of native OS calls.
  • The rest of the implementation should also utilize existing XP interfaces, so that this tool can be used, as defined, across the entire Netscape platform, whereever XP is supported.
  • The source code, and binary, shall be integrated into the Makefile, and build infrastructure so that all tests can name the binary via ..(dot-dot) relative path names. A location for the regress tool needs to be found under /m/src. One possible location is under ns/hardcore. The build engineers (Tarah, etc.) should be consulted prior to fixing a location for the regress tool.
  • FAIL code descriptions

    Output Description
    FAIL: return code = 3 When the test program exits with non zero return code.
    FAIL: Create Process Regress could not run the program or create the process. This usually means a misspelling of the program name, or that you are running on a machine that does not support processes (possibly MAC)
    FAIL: Wait Process Regress could not get the return code of the process for some reason.
    FAIL: Timeout after X seconds The program ran longer than the alloted X seconds and was killed.
    FAIL: Known bug. Bug number = 53416 The bug = tag in the specfile is set, so the test is a known bug.
    FAIL: Known hang A kludge in an older version of regress that recognizes special program names that block forever and outputs this error instead of running them.

    Test Specification File for Regress Tool Testing

    Test Specification for regress
    HTML Output of Regression test on regress

    Specification of Directory Structure / Naming Conventions

  • Regression test suites for each module shall be located in ns/ttools/tests/<component>/<module>/
  • The Makefile in each tests directory should have a tests tag such that one can 'gmake tests' to invoke the testing and generation of the HTML output.

  •  

     

    Regress Special Building Instructions:

    Any Javascript related changes can be made to genjs_template.html.   (see also javascript changes documentation). Once changes are made, run the perl script: makeGenJS.pl which rebuilds the two files: genjs.c and genjs.h.    After which follow normal sectools build instructions.