Running tests#

Use canary run to run tests.

Basic usage#

$ canary run ./basic
INFO: Collecting generator files from basic
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 2 test specs from 2 generators
INFO: Caching test specs
INFO: Created selection 'blue-river'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-41.150000
INFO: Starting process pool with max 1 workers
Job     ID        Status                                          Elapsed      Rank  
───────────────────────────────────────────────────────────────────────────────────
first   4b172fc   SUBMITTED                                                     1/2  
first   4b172fc   STARTED                                                       1/2  
first   4b172fc   PASS (SUCCESS)                                     0.6s       1/2  
second  b1f18b4   SUBMITTED                                                     2/2  
second  b1f18b4   STARTED                                                       2/2  
second  b1f18b4   PASS (SUCCESS)                                     0.3s       2/2  
INFO: 2/2 tests finished with status PASS
INFO: Finished session in 1.05 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults

Filter tests to run by keyword#

canary run -k KEYWORD_EXPR PATH [PATHS...]

where KEYWORD_EXPR is a Python expression such as -k 'fast and regression'. For example

$ canary run -k first ./basic
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from basic
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 2 test specs from 2 generators
INFO: Caching test specs
INFO: Selecting specs based on 1 rules
INFO: Selected 1 test specs
INFO: Excluded 1 test spec during selection
                                                    
  Reason                                     Count  
 ────────────────────────────────────────────────── 
  keyword expression 'first' did not match       1  
                                                    
INFO: Created selection 'aquamarine-obsidian'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-43.215538
INFO: Starting process pool with max 1 workers
Job    ID        Status                                          Elapsed      Rank  
──────────────────────────────────────────────────────────────────────────────────
first  4b172fc   SUBMITTED                                                     1/1  
first  4b172fc   STARTED                                                       1/1  
first  4b172fc   PASS (SUCCESS)                                     0.6s       1/1  
INFO: 1/1 tests finished with status PASS
INFO: Finished session in 0.70 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults

Limit the number of concurrent tests#

canary run --workers=N PATH [PATHS...]

where N is a number of workers. For example,

$ canary run --workers=1 ./basic
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from basic
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 2 test specs from 2 generators
INFO: Caching test specs
INFO: Created selection 'patient-crow'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-44.929816
INFO: Starting process pool with max 1 workers
Job     ID        Status                                          Elapsed      Rank  
───────────────────────────────────────────────────────────────────────────────────
first   4b172fc   SUBMITTED                                                     1/2  
first   4b172fc   STARTED                                                       1/2  
first   4b172fc   PASS (SUCCESS)                                     0.6s       1/2  
second  b1f18b4   SUBMITTED                                                     2/2  
second  b1f18b4   STARTED                                                       2/2  
second  b1f18b4   PASS (SUCCESS)                                     0.3s       2/2  
INFO: 2/2 tests finished with status PASS
INFO: Finished session in 1.04 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults

Set a timeout on the test session#

canary run --timeout session=T PATH [PATHS...]

where T is a duration in Go’s duration format (40s,, 1h20m, 2h, 4h30m30s, etc.) For example,

$ canary run --timeout session=1m ./basic
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from basic
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 2 test specs from 2 generators
INFO: Caching test specs
INFO: Created selection 'brave-breeze'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-46.993075
INFO: Starting process pool with max 1 workers
Job     ID        Status                                          Elapsed      Rank  
───────────────────────────────────────────────────────────────────────────────────
first   4b172fc   SUBMITTED                                                     1/2  
first   4b172fc   STARTED                                                       1/2  
first   4b172fc   PASS (SUCCESS)                                     0.6s       1/2  
second  b1f18b4   SUBMITTED                                                     2/2  
second  b1f18b4   STARTED                                                       2/2  
second  b1f18b4   PASS (SUCCESS)                                     0.3s       2/2  
INFO: 2/2 tests finished with status PASS
INFO: Finished session in 1.05 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults

Run specific test files#

Run a file directly#

Test files can be run directly by passing their paths to canary run

$ canary run ./basic/first/first.pyt
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from basic/first
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 1 test specs from 1 generators
INFO: Caching test specs
INFO: Created selection 'lucid-kernel'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-48.934884
INFO: Starting process pool with max 1 workers
Job    ID        Status                                          Elapsed      Rank  
──────────────────────────────────────────────────────────────────────────────────
first  4b172fc   SUBMITTED                                                     1/1  
first  4b172fc   STARTED                                                       1/1  
first  4b172fc   PASS (SUCCESS)                                     0.6s       1/1  
INFO: 1/1 tests finished with status PASS
INFO: Finished session in 0.69 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults
$ ls -F TestResults
VIEW.TAG
first@

If a path separator is replaced with a colon :, the path is interpreted as root:path. ie, path segments after the : are used as the relative path to the test execution directory:

$ canary run .:basic/first/first.pyt
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from .
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 1 test specs from 1 generators
INFO: Caching test specs
INFO: Created selection 'mellow-night'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-50.527895
INFO: Starting process pool with max 1 workers
Job    ID        Status                                          Elapsed      Rank  
──────────────────────────────────────────────────────────────────────────────────
first  4b172fc   SUBMITTED                                                     1/1  
first  4b172fc   STARTED                                                       1/1  
first  4b172fc   PASS (SUCCESS)                                     0.6s       1/1  
INFO: 1/1 tests finished with status PASS
INFO: Finished session in 0.71 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults
$ ls -F TestResults
VIEW.TAG
basic/

Running tests from a file#

Select tests can be executed by specifying their paths in a json or yaml configuration file with the following layout:

testpaths:
- root: <root>
  paths:
  - <path_1>
  - <path_2>
  ...
  - <path_n>

where <root> is a parent directory of the tests and <path_i> are the file paths relative to <root>. If <root> is a relative path, it is considered relative to the path of the configuration file. Consider, for example, the examples directory tree:

$ canary tree --exclude-results .
.
├── analyze_only
│   └── analyze_only.pyt
├── basic
│   ├── first
│   │   └── first.pyt
│   └── second
│       ├── add.py
│       └── second.pyt
├── canary.json
├── centered_space
│   └── centered_space.pyt
├── copy_and_link
│   ├── copy.txt
│   ├── copy_and_link.1.txt
│   ├── copy_and_link.2.txt
│   ├── copy_and_link.pyt
│   └── link.txt
├── ctest
│   ├── CTestTestfile.cmake
│   ├── resource_group_test_1.py
│   └── resource_group_test_2.py
├── depends_on
│   ├── basic
│   │   ├── a.pyt
│   │   └── depends_on_a.pyt
│   ├── multi
│   │   ├── blt.pyt
│   │   ├── green_eggs_and_ham.pyt
│   │   ├── ingredients.pyt
│   │   ├── kitchen_sink.py
│   │   └── kitchen_sink.pyt
│   ├── parameter
│   │   ├── breakfast.pyt
│   │   └── lunch.pyt
│   └── result
│       ├── depends_on_willfail.pyt
│       └── willfail.pyt
├── enable
│   └── enable.pyt
├── execute_and_analyze
│   └── execute_and_analyze.pyt
├── instance_attributes
│   └── instance_attributes.pyt
├── junit.xml
├── parameterize
│   ├── parameterize1.pyt
│   ├── parameterize2.pyt
│   ├── parameterize3.pyt
│   └── parameterize4.pyt
├── plugin
│   └── my_command.py
├── random_space
│   └── random_space.pyt
├── rebaseline
│   ├── rebaseline.pyt
│   └── test.base.out
├── resources
│   └── resources.pyt
├── status
│   ├── diff.pyt
│   ├── fail.pyt
│   ├── pass.pyt
│   ├── skip.pyt
│   └── timeout.pyt
├── tests.json
├── timeoutx
│   └── timeout.pyt
├── vvt
│   └── test_exec_dir.vvt
└── xstatus
    ├── xdiff-fail.pyt
    ├── xdiff.pyt
    ├── xfail-code.pyt
    ├── xfail-fail.pyt
    └── xfail.pyt

To run only centered_space/centered_space.pyt and parameterize/parameterize2.pyt, write the following to tests.json

{
  "testpaths": [
    {
      "root": ".",
      "paths": ["centered_space/centered_space.pyt", "parameterize/parameterize2.pyt"]
    }
  ]
}

and pass it to canary run:

$ canary run -f tests.json
INFO: Initializing empty canary workspace at .
INFO: Collecting generator files from .
INFO: Collecting generator files from .
INFO: Instantiating generators from collected files
INFO: Generating test specs from generators
INFO: Searching for duplicated tests
INFO: Resolving test spec dependencies
INFO: Generated 12 test specs from 2 generators
INFO: Caching test specs
INFO: Created selection 'raven-pass'
INFO: Selecting test jobs based on runtime environment
INFO: Starting session 2026-06-04T20-45-52.837871
INFO: Starting process pool with max 1 workers
Job                       ID        Status                                          Elapsed      Rank  
─────────────────────────────────────────────────────────────────────────────────────────────────────
parameterize2.a=1.b=2     b741505   SUBMITTED                                                    1/12  
parameterize2.a=1.b=2     b741505   STARTED                                                      1/12  
parameterize2.a=1.b=2     b741505   PASS (SUCCESS)                                     0.7s      1/12  
centered_space.a=0.b=0    18d1ae9   SUBMITTED                                                    2/12  
centered_space.a=0.b=0    18d1ae9   STARTED                                                      2/12  
centered_space.a=0.b=0    18d1ae9   PASS (SUCCESS)                                     0.4s      2/12  
centered_space.a=10.b=0   6fbb430   SUBMITTED                                                    3/12  
centered_space.a=10.b=0   6fbb430   STARTED                                                      3/12  
centered_space.a=10.b=0   6fbb430   PASS (SUCCESS)                                     0.4s      3/12  
centered_space.a=0.b=2    6c9223c   SUBMITTED                                                    4/12  
centered_space.a=0.b=2    6c9223c   STARTED                                                      4/12  
centered_space.a=0.b=2    6c9223c   PASS (SUCCESS)                                     0.4s      4/12  
centered_space.a=0.b=1    f237a83   SUBMITTED                                                    5/12  
centered_space.a=0.b=1    f237a83   STARTED                                                      5/12  
centered_space.a=0.b=1    f237a83   PASS (SUCCESS)                                     0.4s      5/12  
centered_space.a=0.b=-1   4947e35   SUBMITTED                                                    6/12  
centered_space.a=0.b=-1   4947e35   STARTED                                                      6/12  
centered_space.a=0.b=-1   4947e35   PASS (SUCCESS)                                     0.4s      6/12  
centered_space.a=0.b=-2   071c9c3   SUBMITTED                                                    7/12  
centered_space.a=0.b=-2   071c9c3   STARTED                                                      7/12  
centered_space.a=0.b=-2   071c9c3   PASS (SUCCESS)                                     0.4s      7/12  
centered_space.a=5.b=0    d8c3599   SUBMITTED                                                    8/12  
centered_space.a=5.b=0    d8c3599   STARTED                                                      8/12  
centered_space.a=5.b=0    d8c3599   PASS (SUCCESS)                                     0.4s      8/12  
centered_space.a=-5.b=0   c300f2d   SUBMITTED                                                    9/12  
centered_space.a=-5.b=0   c300f2d   STARTED                                                      9/12  
centered_space.a=-5.b=0   c300f2d   PASS (SUCCESS)                                     0.4s      9/12  
parameterize2.a=5.b=6     95fd37e   SUBMITTED                                                   10/12  
parameterize2.a=5.b=6     95fd37e   STARTED                                                     10/12  
parameterize2.a=5.b=6     95fd37e   PASS (SUCCESS)                                     0.4s     10/12  
centered_space.a=-10.b=0  9a6e478   SUBMITTED                                                   11/12  
centered_space.a=-10.b=0  9a6e478   STARTED                                                     11/12  
centered_space.a=-10.b=0  9a6e478   PASS (SUCCESS)                                     0.4s     11/12  
centered_space            97d51af   SUBMITTED                                                   12/12  
centered_space            97d51af   STARTED                                                     12/12  
centered_space            97d51af   PASS (SUCCESS)                                     0.5s     12/12  
INFO: 12/12 tests finished with status PASS
INFO: Finished session in 5.80 s. with returncode 0
INFO: Updating view at /home/docs/checkouts/readthedocs.org/user_builds/canary-wm/checkouts/latest/src/canary/examples/TestResults