Developing with VaRA-TS

First, take a look at our install guide to learn how to set up the tool suite.

The VaRA-TS API Reference contains information about how to work with the tool-suite, as well as how to add your own research tools, Experiments, Reports, Plots, and more.

Debugging with Visual Studio Code shows an example on how to debug benchbuild projects and experiments using the VSCode debugger.

For further information about benchbuild related concepts, like Experiments or Projects, take a look at the benchbuild documentation.

Pre-Commit

We use pre-commit to automatically enforce our code-style guidelines. To activate these checks, you first have to install pre-commit and its hooks:

pip install pre-commit
pre-commit install

Afterwards, the checks will run every time you make a git commit. The same checks also run in our CI and pull requests are required to pass them before merging. It is also possible to run the checks manually:

pre-commit run --all-files

Testing

Tests for the VaRA tool suite are located in the tests directory. The tests are run using pytest but most of the tests are written using unittest syntax.

Mocking the vara configuration

To ensure a flawless test execution, it is important that the order of test execution does not matter, i.e. each single test is idempotent and does not modify the environment. One common problem with this are the vara and benchbuild configurations, as they are stored in a single global object. We therefore provide a helper function replace_config() to set a test-specific vara (and if needed benchbuild) configuration that can be safely modified without affecting other tests. This function can be either used as a decorator similar to unittest.mock or as a context manager.

Test resources

Test resources, like report files or case studies, can be stored in the tests/TEST_INPUTS directory. This directory follows the same structure one would also use for the tool-suites installation environment. The path to this directory can be accessed via the TEST_INPUTS_DIR attribute. If using the replace_config() wrapper or context manager without providing an own configuration, the relevant paths in the replaced configuration object are already pointed to this environment. Keep the data put in this directory as small as possible to avoid bloating the repository.

Warning

Make sure that your tests do not write to this directory to maintain an idempotent test environment. If you really need to write files, use temporary directories instead.


Module: helper_utils

Module for test utility functions.

class tests.helper_utils.UnitTestFixture(*args, **kwargs)[source]

Bases: Protocol

A test fixture that can be used with a TestEnvironment.

copy_to_env(path)[source]

Called when entering the test environment.

The new configs are already in place and the cwd is the tmp dir.

Return type:

None

cleanup()[source]

Called when exiting the test environment.

The old configs are in place again, but the cwd is still the tmp dir.

Return type:

None

class tests.helper_utils.FileFixture(src, dst)[source]

Bases: UnitTestFixture

A file or directory that is copied into the test environment.

copy_to_env(path)[source]

Called when entering the test environment.

The new configs are already in place and the cwd is the tmp dir.

Return type:

None

cleanup()[source]

Called when exiting the test environment.

The old configs are in place again, but the cwd is still the tmp dir.

Return type:

None

class tests.helper_utils.RepoFixture(source)[source]

Bases: UnitTestFixture

A git repository that is cloned into the test environment.

The clone uses a local reference to avoid unnecessary traffic.

copy_to_env(path)[source]

Called when entering the test environment.

The new configs are already in place and the cwd is the tmp dir.

Return type:

None

cleanup()[source]

Called when exiting the test environment.

The old configs are in place again, but the cwd is still the tmp dir.

Return type:

None

class tests.helper_utils.UnitTestFixtures[source]

Bases: object

Collection/factory for test fixtures.

PAPER_CONFIGS = <tests.helper_utils.FileFixture object>
RESULT_FILES = <tests.helper_utils.FileFixture object>
PLOTS = <tests.helper_utils.FileFixture object>
TABLES = <tests.helper_utils.FileFixture object>
ARTEFACTS = <tests.helper_utils.FileFixture object>
TEST_PROJECTS = <tests.helper_utils.RepoFixture object>
static create_file_fixture(src, dst)[source]

Creates a file fixture.

Return type:

UnitTestFixture

static create_project_repo_fixture(project)[source]

Creates a repo fixture for the main source of a project.

Return type:

RepoFixture

class tests.helper_utils.TestEnvironment(required_test_inputs)[source]

Bases: object

Test environment implementation.

The wrapped test is run inside a temporary directory that acts as the varats root folder with a fresh default varats and BenchBuild config. The configurations can be accessed via the usual vara_cfg() and bb_cfg() getters.

Parameters:

required_test_inputs (Iterable[UnitTestFixture]) – test inputs to be copied into the test environment

tests.helper_utils.run_in_test_environment(*required_test_inputs)[source]

Run a test in an isolated test environment.

The wrapped test is run inside a temporary directory that acts as the varats root folder with a fresh default varats and BenchBuild config. The configurations can be accessed via the usual vara_cfg() and bb_cfg() getters.

Parameters:

required_test_inputs (UnitTestFixture) – test inputs to be copied into the test environment

Return type:

Callable[..., Any]

Returns:

the wrapped test function

tests.helper_utils.create_test_environment(*required_test_inputs)[source]

Context manager that creates an isolated test environment.

The wrapped test is run inside a temporary directory that acts as the varats root folder with a fresh default varats and BenchBuild config. The configurations can be accessed via the usual vara_cfg() and bb_cfg() getters.

Parameters:

required_test_inputs (UnitTestFixture) – test inputs to be copied into the test environment

Return type:

TestEnvironment

class tests.helper_utils.DummyGit(remote, local, clone=True, limit=10, refspec='HEAD', shallow=True, version_filter=<function Git.<lambda>>)[source]

Bases: Git

A dummy git source that does nothing.

fetch()[source]

Clone the repository, if needed.

This will create a git clone inside the global cache directory.

Parameters:

version (Optional[str], optional) – [description]. Defaults to None.

Returns:

[description]

Return type:

LocalPath

version(target_dir, version='HEAD')[source]

Create a new git worktree pointing to the requested version.

Parameters:
  • target_dir (str) – The filesystem path where the new worktree should live.

  • version (str) – The desired version the new worktree needs to point to. Defaults to ‘HEAD’.

Returns:

[description]

Return type:

LocalPath

versions()[source]

List all available versions of this source.

Returns:

The list of all available versions.

Return type:

list[Variant]

class tests.helper_utils.ConfigurationHelper[source]

Bases: object

This class is a helper for various tests.

static create_test_config()[source]

This method creates a test configuration.

Return type:

ConfigurationImpl

class tests.helper_utils.BBTestSource(test_versions, local, remote)[source]

Bases: FetchableSource

Source test fixture class.

test_versions: list[str]
property local: str
property remote: str | dict[str, str]
property default: Variant

The default version for this source.

version(target_dir, version)[source]

Fetch the requested version and place it in the target_dir

Parameters:
  • target_dir (str) – The filesystem path where the version should be placed in.

  • version (str) – The version that should be fetched from the local cache.

Returns:

[description]

Return type:

LocalPath

versions()[source]

List all available versions of this source.

Returns:

The list of all available versions.

Return type:

Iterable[Variant]


Debugging with Visual Studio Code

The .vscode/launch.json file in the VaRA-Tool-Suite repository contains a configuration for Visual Studio Code. With F5 the given example is executed. It runs the command benchbuild run -E JustCompile gzip by default, which can be adapted to debug other projects and experiments by changing the arguments that are passed to benchbuild. To step through the JustCompile experiment a breakpoint has to be set in just_compile.py. F9 can be used to set/unset a breakpoint at the current line.