directives#
Before running a test, canary reads the test file looking for “test
directives”. Test directives are instructions for how to setup and allocate
resources needed by the test. The .pyt and .vvt file types use
different directive styles. In the .pyt file type, directives are python
commands contained in the canary.directives namespace. In the .vvt file
type, text directives are preceded with #VVT: and canary will stop
processing further #VVT: directives once the first non-comment
non-whitespace line has been reached in the test script.
The general format for a directive is
.pyt:
import canary
canary.directives.directive_name(*args, **kwargs)
.vvt:
#VVT: directive_name [<option spec>] [: <args>]
where the optional option spec takes the form:
(name=value[, ...])
.vvt directives can be continued on subsequent lines by starting them with #VVT:::
#VVT: directive_name : args
#VVT:: ...
#VVT:: ...
Which is equivalent to
#VVT: directive_name : args ... ...
Most directives take the optional keyword argument when, which is an expression that limits
when the directive is activated. For example, to restrict a directive to be activated only on
linux platforms, add the following:
import canary
canary.directives.directive_name(*args, when='platforms=linux')
or, to restrict processing to linux platforms and when the user has defined the opt option
(by passing -o opt on the command line), add the following:
import canary
canary.directives.directive_name(*args, when='platforms=linux options=opt')
when also accepts a dict, so the previous example can be expressed equivalently as
import canary
canary.directives.directive_name(*args, when={"platforms": "linux", "options": "opt"})
The when expression recognizes the following conditions:
testnameRestrict processing of the directive to this test name
platformsRestrict processing of the directive to certain platform or platforms
optionsRestrict processing of the directive to command line -o options
parametersRestrict processing of the directive to certain parameter names and values
- artifact(file: str, *, when: str | dict[str, str] | None = None, upon: str = 'always') None#
Save
fileas an artifact. This directive is not used by the test directly. Reporters can save a test’s artifacts at their destination. For instance, the artifacts may submitted to CDash as part of the test submission.Usage#
.pyt:import canary canary.directives.artifact(file, *, when=..., upon=...)
.vvt:NAParameters#
when: Restrict processing of the directive to this conditionupon: Define when to save the artifact, based on the status of the job. *success: Save artifacts only when the job succeeds. *failure: Save artifacts only when the job fails or diffs. *always: Always save artifacts (except when jobs time out).
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Examples#
import canary canary.directives.artifacts("file.txt", when="platforms='not darwin'", upon="success")
- baseline(*, src: str | None = None, dst: str | None = None, when: str | dict[str, str] | None = None, flag: str | None = None) None#
Rebaseline a test by running
canary rebaseline ...in the test session directory (or one of its subdirectories)Usage#
.pyt:import canary canary.directives.baseline(src, dst, when=...) canary.directives.baseline(flag=..., when=...)
.vvt:#VVT: baseline (options=..., platforms=..., testname=...) : src,dst #VVT: baseline (options=..., platforms=..., testname=...) : flag
Parameters#
src: The source file.dst: The destination file to replace withsrcwhen: Restrict processing of the directive to this conditionflag: Run the test script with the--FLAGoption on the command line to perform rebaselining.flagshould start with a hyphen (-). The script should parse this value and perform the appropriate rebaselining.
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsparameters: Restrict processing of the directive to certain parameter names and values
Examples#
import canary canary.directives.baseline("file.exo", "file.base_exo", when="platforms='not darwin'")
# VVT: baseline (platforms="not darwin") : file.exo,file.base_exowill replace
file.base_exowithfile.exowhen the baseline stage is ran in its results directory:$ canary run [options] $ cd $(canary -C TestResults location /TESTID) $ canary rebaseline .
- copy(*files: str, src: str | None = None, dst: str | None = None, when: str | dict[str, str] | None = None) None#
Copy files from the source directory into the execution directory.
Usage#
.pyt:import canary canary.directives.copy(*files, when=...) canary.directives.copy(src=..., dst=..., when=...)
.vvt:#VVT: copy (rename, options=..., platforms=..., parameters=..., testname=...) : files ...Parameters#
files: File names to copysrc: Source file to copydst: Copysrcto this destinationwhen: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Note
The
filespositional arguments andsrc,dstkeyword arguments are mutually exclusive.Examples#
Copy files
input.txtandhelper.pyfrom the source directory to the execution directoryimport canary canary.directives.copy("input.txt", "helper.py")
#VVT: copy : input.txt helper.py
Copy files
file1.txtandfile2.txtfrom the source directory to the execution directory and rename themimport canary canary.directives.copy(src="file1.txt", dst="file1_copy.txt") canary.directives.copy(src="file2.txt", dst="file2_copy.txt")
#VVT: copy (rename) : file1.txt,file1_copy.txt file2.txt,file2_copy.txt
Copy files
spam.txtandeggs.txtfrom the source directory to the execution directory if the parameterbreakfast=spamorbreakfast=eggs, respectivelyimport canary canary.directives.parameterize("breakfast", ("spam", "eggs")) canary.directives.copy("spam.txt", when={"parameters": "breakfast=spam"}) canary.directives.copy("eggs.txt", when={"parameters": "breakfast=eggs"})
#VVT: parameterize : breakfast = spam eggs #VVT: copy (parameters='breakfast=spam') : spam.txt #VVT: copy (parameters='breakfast=eggs') : eggs.txt
- depends_on(*arg: str | dict[str, Any] | DependencySelector, when: str | dict[str, str] | None = None, **kwargs) None#
Require that test
argrun before this test.Usage#
.pyt:import canary canary.directives.depends_on(name, when=...) canary.directives.depends_on({"job": name, "when": ..., "expects": ...}, when=...) canary.directives.depends_on([{"job": name, "when": ..., "expects": ...}], when=...)
.vvt:#VVT: depends on (result=..., expect=..., options=..., platforms=..., testname=...) : argParameters#
arg: The test that should run before this test. Wildcards are allowed.when: Restrict processing of the directive to this condition
VVT Parameters#
result: Control whether or not this test runs based on the result of the dependent test. By default, a test will run if its dependencies pass or diff.expect: How many dependencies to expect.
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Examples#
Run
spamifbazpasses or diffs..pyt:# spam.pyt import canary canary.directives.depends_on("baz") def test(): self = canary.testinstance baz = self.dependencies[0] print(f"baz's results can be found in {baz.working directory}")
.vvt:# spam.vvt # VVT: depends on: baz import vvtest_util as vvt def test(): working directory = vvt.DEPDIRS[0] print(f"baz's results can be found in {working directory}")
Run
spamregardless ofbaz’s result:.pyt:# spam.pyt import canary canary.directives.depends_on({"job": "baz", "when": "always"}) def test(): self = canary.testinstance baz = self.dependencies[0] print(f"baz's results can be found in {baz.working directory}")
.vvt:# spam.vvt # VVT: depends on (result=*) : baz import vvtest_util as vvt def test(): working directory = vvt.DEPDIRS[0] print(f"baz's results can be found in {working directory}")
spamdepends only on the serialbaztest:.pyt:# spam.pyt import canary canary.directives.depends_on("baz.cpus=1") def test(): self = canary.testinstance baz = self.dependencies[0] print(f"baz's results can be found in {baz.working directory}")
.vvt:# spam.vvt # VVT: depends on: baz.np=1 import vvtest_util as vvt def test(): working directory = vvt.DEPDIRS[0] print(f"baz's results can be found in {working directory}")
- exclusive(*, when: str | dict[str, str] | None = None) None#
Do not run this test in parallel with any other test.
Usage#
.pyt:import canary canary.directives.exclusive(*, when=...)
.vvt:NAParameters#
when: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Examples#
import canary canary.directives.exclusive(when="platforms='not darwin'")
- generate_composite_base_case(*, when: str | dict[str, str] | None = None, flag: str | None = None, script: str | None = None) None#
Create an composite base job that depends on all of the parameterized jobs generated by this file.
The composite base job will run after all other parameterized jobs and can be used to to ensure that the overall behavior of the parameterized jobs. For example, a parameter may represent a step size and the composite base job will verify convergence as the step size parameter is reduced.
The composite base job has access to all of parameterized jobs’ parameters through the
dependenciesattribute.Usage#
.pyt:import canary canary.directives.generate_composite_base_case(*, flag=None, script=None, when=...)
.vvt:#VVT: analyze (options=..., platforms=..., testname=...) : (flag|script)Parameters#
when: Restrict processing of the directive to this conditionflag: Run the test script with the--FLAGoption on the command line.flagshould start with a hyphen (-). The script should parse this value and perform the appropriate analysis.script: Runscriptduring the analysis phase (instead of the test file).
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
References#
Examples#
import canary canary.directives.generate_composite_base_case(flag="--base", when="platforms='not darwin'") canary.directives.parameterize("a,b", [(1, 2), (3, 4)])
# VVT: analyze (platforms="not darwin") : --analyze # VVT: parameterize : a,b = 1,2 3,4
will run an analysis job after jobs
[a=1,b=3]and[a=2,b=4]have run to completion. Thecanary.testinstanceandvvtest_utilmodules will contain information regarding the previously run jobs so that a collective analysis can be performed.For either file type, the script must query the command line arguments to determine the type of test to run:
import argparse import sys import canary canary.directives.generate_composite_base_case(flag="--base", when="platforms='not darwin'") canary.directives.parameterize("a,b", [(1, 2), (3, 4)]) def test() -> int: ... def base() -> int: ... def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--base", action="store_true") args = parser.parse_args() if args.analyze: return base() return test() if __name__ == "__main__": sys.exit(main())
- analyze(*, when: str | dict[str, str] | None = None, flag: str | None = None, script: str | None = None) None#
Create an composite base job that depends on all of the parameterized jobs generated by this file.
The composite base job will run after all other parameterized jobs and can be used to to ensure that the overall behavior of the parameterized jobs. For example, a parameter may represent a step size and the composite base job will verify convergence as the step size parameter is reduced.
The composite base job has access to all of parameterized jobs’ parameters through the
dependenciesattribute.Usage#
.pyt:import canary canary.directives.generate_composite_base_case(*, flag=None, script=None, when=...)
.vvt:#VVT: analyze (options=..., platforms=..., testname=...) : (flag|script)Parameters#
when: Restrict processing of the directive to this conditionflag: Run the test script with the--FLAGoption on the command line.flagshould start with a hyphen (-). The script should parse this value and perform the appropriate analysis.script: Runscriptduring the analysis phase (instead of the test file).
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
References#
Examples#
import canary canary.directives.generate_composite_base_case(flag="--base", when="platforms='not darwin'") canary.directives.parameterize("a,b", [(1, 2), (3, 4)])
# VVT: analyze (platforms="not darwin") : --analyze # VVT: parameterize : a,b = 1,2 3,4
will run an analysis job after jobs
[a=1,b=3]and[a=2,b=4]have run to completion. Thecanary.testinstanceandvvtest_utilmodules will contain information regarding the previously run jobs so that a collective analysis can be performed.For either file type, the script must query the command line arguments to determine the type of test to run:
import argparse import sys import canary canary.directives.generate_composite_base_case(flag="--base", when="platforms='not darwin'") canary.directives.parameterize("a,b", [(1, 2), (3, 4)]) def test() -> int: ... def base() -> int: ... def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--base", action="store_true") args = parser.parse_args() if args.analyze: return base() return test() if __name__ == "__main__": sys.exit(main())
- enable(*args: bool, when: str | dict[str, str] | None = None) None#
Explicitly mark a test to be enabled (or not)
Usage#
.pyt:import canary canary.directives.enable(arg, when=...)
.vvt:#VVT: enable (options=..., platforms=..., testname=...) : argParameters#
arg: Optional (default:True). IfTrue, enable the test. IfFalse, disable the testwhen: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Examples#
Explicitly disable a test
import canary canary.directives.enable(False)
#VVT: enable : false
Enable the test if the platform name is not “ATS”
import canary canary.directives.enable(True, when="platforms='not ATS'")
#VVT: enable (platform="not ATS") : true
More examples:
import canary canary.directives.enable(True, when="testname=foo platform='Darwin or Linux'") canary.directives.enable(True, when="platform='not Windows' options='not debug'") canary.directives.enable(False, when="testname=foo")
The above examples are equivalent to:
import canary canary.directives.enable(True, when={"testname": "foo", "platform": "Darwin or Linux"}) canary.directives.enable(True, when={"platform": "not Windows", "options": "not debug"}) canary.directives.enable(False, when={"testname": "foo"})
The
vvtequivalent are#VVT: enable (testname=foo, platform="Darwin or Linux") : true #VVT: enable (platform="not Windows", options="not debug") : true #VVT: enable (testname=foo) : false
- include(file: str, *, when: str | dict[str, str] | None = None) None#
Include the contents of
fileat the point where the directive appears.Usage#
.pyt:NA.vvt:#VVT: include (options=..., platforms=...) : file #VVT: insert directive file (options=..., platforms=...) : file
Parameters#
file: The file to includewhen: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:platforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptions
Notes#
included files canincludeother filesIf
fileis a relative path, it is assumed relative to the fileincluding itThe alias
insert directive fileis also recognized
Examples#
# VVT: include : file.txtwill include directives from
file.txtinto the current test.
- keywords(*args: str, when: str | dict[str, str] | None = None) None#
Mark a test with keywords. The main use of test keywords is to filter a set of tests, such as selecting which tests to run.
Usage#
.pyt:import canary canary.directives.keywords(*args, when=...)
.vvt:#VVT: keywords (parameters=..., testname=...) : args...Parameters#
args: list of keywordswhen: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameparameters: Restrict processing of the directive to certain parameter names and values
Implicit keywords#
The following implicit keywords are defined:
The test name
The test file basename (regardless of testname settings)
The names of parameters, e.g.
import canary canary.directives.parameterize("meshsize", (0.1, 0.01, 0.001))
would have “meshsize” as a keyword.
- The results of running the test are added as keywords. The result strings are
ready: the test is ready to be runpass: the test ran and completed successfullydiff: the test ran and completed with a numerical differencefail: the test ran but crashed for some reason (exited with a non-zero exit status)timeout: the test ran out of time and was killed. A test that times out is also considered to have failed.
Examples#
import canary canary.directives.keywords("3D", "mhd", "circuit")
#VVT: keywords : 3D mhd circuit
import canary canary.directives.keywords("3D", "mhd", when="testname=spam parameters='cpus>1'")
#VVT: keywords (testname=spam, parameters="np>1") : 3D mhd
- link(*files: str, src: str | None = None, dst: str | None = None, when: str | dict[str, str] | None = None) None#
Link files from the source directory into the execution directory.
Usage#
.pyt:import canary canary.directives.link(*files, when=...) canary.directives.link(src=..., dst=..., when=...)
.vvt:#VVT: link (rename, options=..., platforms=..., parameters=..., testname=...) : files ...Parameters#
files: File names to linksrc: Source file to linkdst: Linksrcto this destinationwhen: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Note
The
filespositional arguments andsrc,dstkeyword arguments are mutually exclusive.Examples#
Link files
input.txtandhelper.pyfrom the source directory to the execution directoryimport canary canary.directives.link("input.txt", "helper.py")
#VVT: link : input.txt helper.py
Link files
file1.txtandfile2.txtfrom the source directory to the execution directory and rename themimport canary canary.directives.link(src="file1.txt", dst="file1_link.txt") canary.directives.link(src="file2.txt", dst="file2_link.txt")
#VVT: link (rename) : file1.txt,file1_link.txt file2.txt,file2_link.txt
- owners(*args: str) None#
Specify a test’s owner[s]
Usage#
.pyt:import canary canary.directives.owners("name1", "name2", ...)
.vvt:NAParameters#
args: The list of owners
- owner(*args: str) None#
Specify a test’s owner[s]
Usage#
.pyt:import canary canary.directives.owners("name1", "name2", ...)
.vvt:NAParameters#
args: The list of owners
- parameterize(names: str | Sequence[str], values: Sequence[Sequence[Any] | Any], *, when: str | dict[str, str] | None = None, type: enums = enums.list_parameter_space, samples: int = 10, random_seed: float = 1234.0) None#
Add new invocations to the test using the list of argvalues for the given argnames.
Usage#
.pyt:import canary canary.directives.parametrize(argnames, argvalues, when=..., type=None)
.vvt:#VVT: parametrize (options=...,platforms=...,testname=...) : argnames = argvaluesParameters#
argnames: A comma-separated string denoting one or more argument names, or a list/tuple of argument strings.argvalues: If only oneargnamewas specified,argvaluesis a list of values. IfNargnameswere specified,argvaluesis a 2D list of values where each column are the values for its respectiveargname.when: Restrict processing of the directive to this conditiontype: (.pytonly) Generate parameters using this typesamples: (.pytonly) Generate this many random elements (applicable only iftype=canary.random_parameter_space)
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatform: Restrict processing of the directive to certain platform or platformsoption: Restrict processing of the directive to command line-ooptions
Special argnames#
cpusinterpreted to mean “number of processing cores”. If thecpusparameter is not defined, the test is assumed to use 1 processing core.gpusinterpreted to mean “number of gpus”. If thegpusparameter is not defined, the test is assumed to use 0 gpus.
References#
Examples#
The following equivalent test specifications result in 4 test instantiations
test1.pyt:# test1 canary.directives.parameterize("cpus", (4, 8, 12, 32))
test1.vvt:# test1 #VVT: parameterize : np = 4 8 12 32
4 test jobs: ├── test1[cpus=4] ├── test1[cpus=8] ├── test1[cpus=12] ├── test1[cpus=32]
argnamescan be a list of parameters with associatedargvalues, e.g.test1.pyt:# test1 canary.directives.parameterize("a,b", ((1, 2), (3, 4), (5, 6)))
test1.vvt:# test1 #VVT: parameterize : a,b = 1,2 3,4 5,6
3 test jobs: ├── test1[a=1,b=2] ├── test1[a=3,b=4] ├── test1[a=5,b=6]
parameterizecan be called multiple times. When multiple parameterize directives are given, the Cartesian product of each is taken to form the set of parameters, e.g.test1.pyt:# test1 canary.directives.parameterize("a,b", [("a1", "b1"), ("a2", "b2")]) canary.directives.parameterize("x", ["x1", "x2"])
results in the following test invocations:
4 test jobs: ├── test1[a=a1,b=b1,x=x1] ├── test1[a=a1,b=b1,x=x2] ├── test1[a=a2,b=b2,x=x1] ├── test1[a=a2,b=b2,x=x2]
- cpus(arg: int, *, when: str | dict[str, str] | None = None) None#
This test requires this many CPUs
Usage#
.pyt:import canary canary.directives.cpus(arg, when=...)
.vvt:NAParameters#
arg: The number of CPUs required by this test.
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatform: Restrict processing of the directive to certain platform or platformsoption: Restrict processing of the directive to command line-ooptions
Notes#
Use
cpus(int)to set a single, fixed resource requirement for a job without creating additional test instantiations.Test naming reflects only parameters introduced via parameterize(). Therefore, when CPUs are set via
cpus(arg),cpus=<arg>are not appended to the generated test name. If you want distinct named variants such as...cpus=8, useparameterize("cpus", ...)instead.
- gpus(arg: int, *, when: str | dict[str, str] | None = None) None#
This test requires this many GPUs
Usage#
.pyt:import canary canary.directives.gpus(arg, when=...)
.vvt:NAParameters#
arg: The number of GPUs required by this test.
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatform: Restrict processing of the directive to certain platform or platformsoption: Restrict processing of the directive to command line-ooptions
Notes#
Use
gpus(int)to set a single, fixed resource requirement for a job without creating additional test instantiations.Test naming reflects only parameters introduced via parameterize(). Therefore, when GPUs are set via
gpus(arg),gpus=<arg>are not appended to the generated test name. If you want distinct named variants such as...gpus=8, useparameterize("gpus", ...)instead.
- preload(arg: str, *, when: str | dict[str, str] | None = None, source: bool = False) None#
Load shell shell script before test execution
Usage#
.pyt:import canary canary.directives.preload(arg, *, when=..., source=False):
.vvt:# VVT: preload (options=..., platforms=..., testname=...) : [source-script] script_nameWarning
The
preloadcurrently has no effect. Usecanary.shell.sourceinstead, see Sourcing rc scripts during test execution.
- load_module(name: str, *, use: str | None = None, when: str | dict[str, str] | None = None) None#
Load a module before a test is executed.
Usage#
.pyt:import canary canary.directives.load_module(name, when=..., use=...)
.vvt:NAParameters#
name: The name of the moduleuse: Add this directory toMODULEPATHwhen: Restrict processing of the directive to this condition
Examples#
import sys import canary canary.directives.load_module("gcc")
will load the
gccmodule before the test is executed.
- source(name: str, *, when: str | dict[str, str] | None = None) None#
Source a shell rc file before a test is executed.
Usage#
.pyt:import canary canary.directives.source(name, when=...)
.vvt:NAParameters#
name: The name of the rc filewhen: Restrict processing of the directive to this condition
Examples#
import sys import canary canary.directives.source("setup-env.sh")
will source the
setup-env.shfile before the test is executed.
- set_attribute(*, when: str | dict[str, str] | None = None, **attributes: Any) None#
Set an attribute on the test
Usage#
.pyt:import canary canary.directives.set_attribute(*, when=..., **attributes)
.vvt:NAParameters#
when: Restrict processing of the directive to this conditionattributes:attr:valuepairs
Examples#
import sys import canary canary.directives.set_attribute(program="program_name")
will set the attribute
programon the job with value “program_name”.
- filter_warnings(arg: bool) None#
Don’t write warnings to the console when scanning files.
Usage#
.pyt:import canary canary.directives.filter_warnings(arg)
.vvt:#VVT: filter_warnings : python_expressionParameters#
arg: IfTrue, the test will be skipped.
.vvt Parameters#
python_expression: String that is evaluated and cast to abool. If the result isTruewarnings at file scanning time will be filtered.
Examples#
import sys import canary canary.directives.filter_warnings(True)
#VVT: filter_warnings : trueEvaluation namespace#
python_expressionis evaluated in a minimal namespace consisting of theosmodule,sysmodule, andimportablefunction.
- skipif(arg: bool, *, reason: str) None#
Conditionally skip tests
Usage#
.pyt:import canary canary.directives.skipif(arg, *, reason)
.vvt:#VVT: skipif : python_expressionParameters#
arg: IfTrue, the test will be skipped.reason: The reason the test is being skipped.
.vvt Parameters#
python_expression: String that is evaluated and cast to abool. If the result isTruethe test will be skipped.
Examples#
import sys import canary canary.directives.skipif( sys.platform == "Darwin", reason="Test does not run on Apple" )
#VVT: skipif (reason=Test does not run on Apple) : sys.platform == "Darwin"will skip the test if run on Apple hardware.
If
reasonis not defined,canaryreports the reason as"python_expression evaluated to True".Checking module availability#
A test may be skipped if a module is not importable by using the
importablefunction.importable(module_name)evaluates toTrueifmodule_namecan be imported otherwise,False. For example,#VVT: skipif : not importable("numpy")would skip the test if
numpywas not available.Evaluation namespace#
python_expressionis evaluated in a minimal namespace consisting of theosmodule,sysmodule, andimportablefunction.
- sources(*args: str, when: str | dict[str, str] | None = None) None#
- stages(*args: str) None#
- testname(arg: str) None#
Set the name of a test to one different from the filename and/or define multiple test names (multiple test instances) in the same file.
Usage#
.pyt:import canary canary.directives.name(arg)
.vvt:testname : arg
Parameters#
arg: The alternative test name.
Examples#
For the test file
a.pytcontainingimport canary canary.directives.testname("spam") ...
a test instance with name “spam” would be created, even though the file is named
a.pyt.
testnamecan be called multiple times. Each call will create a new test instance with a different name, e.g..pyt:import canary canary.directives.testname("foo") canary.directives.testname("bar") def test(): self = canary.get_instance() if self.name == "foo": do_foo_stuff() elif self.name == "bar": do_bar_stuff()
.vvt:#VVT: testname : foo #VVT: testname : bar import vvtest_util as vvt def test(): if vvt.NAME == "foo": do_foo_stuff() elif vvt.NAME == "bar": do_bar_stuff()
This file would result in two tests: “foo” and “bar”.
- name(arg: str) None#
Set the name of a test to one different from the filename and/or define multiple test names (multiple test instances) in the same file.
Usage#
.pyt:import canary canary.directives.name(arg)
.vvt:testname : arg
Parameters#
arg: The alternative test name.
Examples#
For the test file
a.pytcontainingimport canary canary.directives.testname("spam") ...
a test instance with name “spam” would be created, even though the file is named
a.pyt.
testnamecan be called multiple times. Each call will create a new test instance with a different name, e.g..pyt:import canary canary.directives.testname("foo") canary.directives.testname("bar") def test(): self = canary.get_instance() if self.name == "foo": do_foo_stuff() elif self.name == "bar": do_bar_stuff()
.vvt:#VVT: testname : foo #VVT: testname : bar import vvtest_util as vvt def test(): if vvt.NAME == "foo": do_foo_stuff() elif vvt.NAME == "bar": do_bar_stuff()
This file would result in two tests: “foo” and “bar”.
- timeout(arg: str | float | int, *, when: str | dict[str, str] | None = None) None#
Specify a timeout value for a test
Usage#
.pyt:import canary canary.directives.timeout(arg, when=...)
.vvt:# VVT: timeout (options=..., platforms=..., parameters=..., testname=...) : argParameters#
arg: The time in seconds. Natural language forms such as “20m”, “1h 20m”, and HH:MM:SS such as “2:30:00” are also allowed and converted to seconds.when: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
Notes#
The timeout for a test is determined based on the following rules:
if the test has an explicit timeout set by
canary.directives.timeout, use it;if the test has a keyword that appears in the
test:timeout:configuration section, use it;otherwise, use a the default timeout.
- xdiff(*, when: str | dict[str, str] | None = None) None#
The test is expected to diff.
Usage#
.pyt:import canary canary.directives.xdiff(when=...)
Parameters#
when: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values
- xfail(*, code: int = -1, when: str | dict[str, str] | None = None) None#
The test is expected to fail (return with a non-zero exit code). If
code > 0and the exit code is notcode, the test will be considered to have failed.Usage#
.pyt:import canary canary.directives.xfail(code=-1, when=...)
Parameters#
code: The expected return code.-1considers any non-zero return code to be a pass.when: Restrict processing of the directive to this condition
The
whenexpression is limited to the following conditions:testname: Restrict processing of the directive to this test nameplatforms: Restrict processing of the directive to certain platform or platformsoptions: Restrict processing of the directive to command line-ooptionsparameters: Restrict processing of the directive to certain parameter names and values