-
Notifications
You must be signed in to change notification settings - Fork 2
The parameterize directive
This section is for reference; see parameterizing a test for more detail on how to use parameters.
To parameterize on a single parameter name:
#VVT: parameterize : name = value1 value2 value3
This will create three test instances, one with name=value1
, one with name=value2
, and one with name=value3
.
A parameter name must be a valid shell or Python variable.
To parameterize on grouped parameter names:
#VVT: parameterize : nameA,nameB = valueA1,valueB1 valueA2,valueB2 valueA3,valueB3
This will create three test instances:
-
nameA=valueA1
andnameB=valueB1
-
nameA=valueA2
andnameB=valueB2
-
nameA=valueA3
andnameB=valueB3
Line continuation is frequently used with parameterized grouping to make it more readable:
#VVT: parameterize : nameA, nameB = valueA1, valueB1
#VVT:: valueA2, valueB2
#VVT:: valueA3, valueB3
When multiple parameterize directives are given, the Cartesian product of each is taken to form the set of test instances. For example,
#VVT: parameterize : nameA = valueA1 valueA2
#VVT: parameterize : nameB = valueB1 valueB2 valueB3
will produce 2*3=6 test instances:
-
nameA=valueA1
andnameB=valueB1
-
nameA=valueA1
andnameB=valueB2
-
nameA=valueA1
andnameB=valueB3
-
nameA=valueA2
andnameB=valueB1
-
nameA=valueA2
andnameB=valueB2
-
nameA=valueA2
andnameB=valueB3
The allowable common attributes are "testname", "platform", and "option". These decide whether the directive is processed or not.
The "staged" attribute causes the test instances corresponding to the parameter values to be run sequentially and in the same execution directory. See the section on Using staging in parameterized tests for more information, but an example syntax is
#VVT: parameterize (staged) : name = value1 value2 value3
By default, the type of each parameter value in the vvtest_util.py
file is a string. The autotype
attribute tries to determine the type automatically from the values of a parameter. Consider
#VVT: parameterize (autotype) : np = 1 4 16
#VVT: parameterize (autotype) : foo,bar = a,0.1 b,0.01 c,0.001
import vvtest_util as vvt
print ( 'type of np '+str(type(vvt.np)) )
print ( 'type of foo '+str(type(vvt.foo)) )
print ( 'type of bar '+str(type(vvt.bar)) )
In this case, the Python type of the np
variable will be int
, foo
will be str
, and bar
will be float
.
The autotype
logic does this:
- Try casting each parameter value to an
int
. If success, use typeint
- Try casting each parameter value to a
float
. If success, use typefloat
- If neither of those, then use type
str
These attributes provide precise control over the types of each parameter. They cannot be mixed with the autotype
attribute for any single parameterize directive.
If one type attribute is specified, then all parameters will take on that variable type. In this example, the np
parameter will be an int
and both dt
and dh
will be float
:
#VVT: parameterize (int) : np = 1 4 16
#VVT: parameterize (float) : dt,dh = 1,2 0.1,0.2
When more than one variable type is specified, then the number of type specifiers must match the number of variable names in a group, such as
#VVT: parameterize (int,float,int) : np,dt,N = 1,0.1,10 2,0.2,20
The parameter names and values can be specified from an external script using the generator
attribute, such as
#VVT: parameterize (generator) : myscript --my-args
A generator script must print to "stdout" a JSON formatted list of dictionaries with the parameter names and values. For example
from json import dumps
print ( dumps( [ {'np':1, 'dt':0.1, 'N':10}, {'np':4, 'dt':0.05, 'N':20} ] ) )
If the script is executable, it will execute it. Otherwise it is assumed to be Python and the current interpreter executable is used to run the script. Note that the script name can be the test file itself and command line arguments used to branch to a function for printing the parameters.
Some constraints:
- Only the
json.dumps()
output should be written to "stdout" - it must fit on a single line (no pretty printing!) - The format is reconstructable using Python
json.loads()
- The format is a list of dictionaries
- Each dictionary must be the same size and have the same keys (the parameter names)
- The parameter values must be
int
,float
, orstr
- Currently, the names and values must be the same for multiple calls
The types are taken from the JSON reconstruction (but can only be int
, float
, and str
).
The repeatable or deterministic constraint implies that any "random" values must use a seed so that the same values are generated.
The generator command has ${NAME}
and ${PLATFORM}
replaced with the test name and the current platform name before the command is executed.
The parameter generator script prints a line specifying the parameter names and values of each test. An optional second line can be printed by the generator script to specify a test dependency for each test. The line must be a single JSON line of the form
[ {'name':{'param1':val1, 'param2':val2}}, ... ]
It must be a list of the same length as the first line. Each entry is dictionary mapping the dependency test name to the dependency test parameter names and values.
This will define a single test dependency for each test specified in the first line.
Actually, each dependency list entry can be one of
- A dictionary mapping test names to a dictionary of the parameter names and values
- None (a JSON null), which means do not add a dependency
- A string containing a shell-style glob pattern
Example generator script output with a dependency line:
[{"A": 1, "B": "b1"}, {"A": 2, "B": "b2"}, {"A": 3, "B": "b3"}]
[null, {"C": {"A": 2, "B": "b2"}}, "dep.A=*"]
The second entry in this example means the current test with parameters A=2 & B='b2' depends on test "C" with parameters A=2 & B='b2'.
Currently, multiple dependencies for a test can be given as long as they have different test names. A multiple dependency example is
{"C": {"A": 2}, "D": {"A": 2}}
which means the test depends on two tests:
- test name "C" with param A=2
- test name "D" with param A=2