
PFUNIT MPI PARALLEL SIMPLE PARAMETERIZED TEST

FILE:      README
DIRECTORY: Examples/MPI_SimpleParameterizedTest
VERSION:   2013-1209  M. Rilee mike@rilee.net

The files here provide an example of how to write parameterized, MPI
parallel tests using TestCases and the preprocessor
(${PFUNIT}/bin/pFUnitParser.py).  For parameterized, MPI parallel, or
TestCases on their own, please see Examples/ParameterizedTest,
Examples/MPI_Halo, or Examples/Fixture respectively.

To make and run the test example, type "make all" in this directory.

There are three files in the tests directory:
- GNUmakefile
- testSuites.inc
- parameterizedTests.pf

A more extensive project would likely also have a src directory for
the user's code, to which the tests would refer.

GNUMAKEFILE
The GNUmakefile shows how to run the parser.  
$ ${PFUNIT}/bin/pFUnitParser.py) parameterizedTests.pf parameterizedTests.F90

TESTSUITE.INC
The include file "testSuites.inc" tells the preprocessor to generate
code for TestSuites listed therein.  The suite names are based on the
TestCases provided in the preprocessor input file or the name of the
input file itself.

PARAMETERIZEDTESTS.PF
The pFUnit preprocessor input file (`parameterizedTests.pf`) contains
source code for a module and directives that guide the preprocessor in
generating the tests' compilable source code.  At this writing there
is more manually written boilerplate code than we would like, which at
some point we hope to automate via the parser's code generator.
Current directives demonstrated in the example follow.

@PARAMETER
To notify the preprocessor about parameters to iterate over, we use
the @Parameter directive immediately before the type extension
declaration.  E.g.

@Parameter
type, extends(AbstractParameter) :: peCase
   integer :: p1
   integer :: p2
end type

This will then be parsed and used to set up a loop over an associate
statement during code generation.

@TESTCASE
To set up the test iteration over the parameters we use an extension
of the abstract ParameterizedTestCase. In the present case we extend
MPITestCase, which extends ParameterizedTestCase, because we're
developing parameterized MPI tests.  In addition to the parameters
themselves, we must declare and implement/override several type bound
procedures with new behaviors.  

Note: Currently the preprocessor supports a single TestCase (and
multiple tests).

Important procedures to implement for the parameterized TestCase
include a constructor, getParameters, and getParameterString.  Due to
Fortran's inheritance model, we must also define the subroutine
runMethod, which needn't vary from what's in the example code.

CONSTRUCTOR
The preprocessor expects to find a constructor with the same base name
as added in testSuites.inc.  This is demonstrated in the example via
the interface Test_Parameters which declares the module procedure
newTest, the actual constructor. The signature of the constructor for
our MPI based case includes number of processors requested
(e.g. npes), followed by the parameters, in the order declared in the
@Parameter directive.

GETPARAMETERS
The preprocessor uses the getParameters method to set up the test
iteration, returning an array of the parameter cases.  The user
defines the parameter values for the tests here.

GETPARAMETERSTRING
This function returns a string based on the values of the parameters
passed to the constructor during test instantiation.  This string is
used to identify the test case and is printed out when a test fails.

@MPITEST( npes=[<npes>] )
One or more tests may be defined as methods annotated by the @mpiTest
directive. The directive's argument is the number of processing
elements requested for the test.  pFUnit library calls or @assert
directives may be used within the test subroutine itself.  Parameters
are passed to this test upon construction of the TestCase object,
which occurs in an associate statement within the body of a loop over
the parameters in the TestSuite code generated by the preprocessor.

TODO: Automate the above process to minimize hand-coding in favor of
preprocessor code generation.


