Skip to content

REP-001: Various rez-tests enhancements #665

Open
@JeanChristopheMorinPerso

Description

Proposal to improve rez-test.

  • Add run_on field for tests
  • Add way to run 'all' tests (regardless of run_on)
  • Add rez-test --interactive option
  • Add rez-test --inplace option
  • Pass custom arguments when running a test
  • Add variant iteration options

Note: Some of these features clearly change rez-test into something a bit more general, so the name may have to change (to rez-task for eg). However we will consider this as a separate issue.

1. Add "run_on" field for tests.

This would define when the test gets run. Possible values:

  • "default" (the default): Run when rez-test is run with no TEST arg(s).
  • "pre-install": Run before a package install (not release); abort the install on failure.
  • "pre-release": Run before package release, abort release on failure.
  • "explicit": Only run if explicitly specified by rez-test, as a TEST arg.

The param would be a list, so a test can run on multiple of these events.

For pre-install/release, what would happen is:

  1. The package source is built;
  2. It is then installed to a temp dir.
  3. This temp installation is then used to run the test(s);
  4. If the tests pass, a second installation is performed to the correct location.

2. Run all tests defined by a package

I feel the need to be able to run all tests defined by a package, no matter what their run_on is set to.

rez-test <package> all

That would introduce a "reserved" target name all, but I think we should still let anyone refine its own all target, hence the quotes around the reserved word ;)

3. Pass custom arguments when running a test

It is common to have to modify the commands of the tests for a package while developing that said package. There is multiple reasons why we do so. For example, you might want to increase the verbosity of your tests only when developing and keep the verbosity lower in your CI tests. The other common reason is to choose a custom target inside a particular test so you can iterate faster and avoid running unnecessary tests.

For example, let's say we have:

tests = {
    'unit': {
        'command': 'pytest {root}/tests/unit_tests'
        'requires': 'pytest'
    }
}

where tests/unit_tests contains multiple test files and each file contains tests with markers (pytest jargon. A marker is basically a way to group the tests so that you can selectively choose which one to run in the command line).

I propose to add a functionality to make rez-test package unit -- -v -m myMarker valid and that would run pytest {root}/tests/unit_tests -v -m myMarker.

The immediate benefit is that it's faster and more intuitive. The second is that it can avoid mistakenly committing the modifications to the tests variable.

Note that passing custom arguments should only be possible if only one test is being run.

4. More execution options

Specifically:

  • A rez-test --interactive option. Puts you into an interactive shell for the nominated test. From here you could then use...
  • A rez-test --inplace option. Ie, run the tests in the current env, if it provides all the required packages. If not, give an error.

5. Variant iteration options

Many times, it makes sense to run a test on all variants of a package. Currently that doesn't happen (variants aren't iterated over at all) because there's not currently a reliable way to resolve to an explicit variant in rez. However, until such time as we have the required feature to do this, we could get pretty close, and it's probably worth doing (the code needed to do this is minimal).

Some things to consider:

  • Some tests won't make sense to run over multiple variants (eg linting).
  • Some tests might only make sense to run on certain variants (eg just variants requiring "maya")

How to express this? Perhaps a new variant tests field. For eg, with variant: True, the test will be run on every variant. If False/not present, it will just run on one variant (matching current behaviour). If a dict containing "requires", it will run only on variants overlapping with the given request list; furthermore, if the requires list conflicts with a variant, that variant is skipped.

For example, given:

variants = [
  ["python-3"],
  ["python-3", "maya-2018"],
  ["python-3", "maya-2019"]
]

tests = {
  "linter": {
    "command": "pylint ...",
    "variant": False
  },
  "core": {
    "command": "python {root}/run_core_unit_tests.py",
    "variant": {
      "requires": ["!maya"]
    }
  }
}
  • The linter test would run just once, not per variant;
  • The 'core' test would run on every variant not containing maya

Metadata

Metadata

Assignees

No one assigned

    Labels

    REPREPs are Rez enhancement proposals that need in-depth discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions