How DiscoveryMixIn Converts Cartesian Config Parameters to Avocado Test Parameters
The DiscoveryMixIn class transforms raw Cartesian configuration dictionaries into structured Avocado test parameters by resolving test identifiers, applying backend-specific naming rules, and wrapping the result into a format compatible with the Avocado nrunner API.
In the avocado-framework/avocado-vt repository, the bridge between legacy Cartesian configuration files and the modern Avocado test runner is implemented in the DiscoveryMixIn class. Located in avocado_vt/discovery.py, this mixin provides the convert_parameters() method that translates the flat key-value pairs of a Cartesian config into the enriched parameter structure required by Avocado-VT's resolver and loader components.
The Conversion Pipeline in DiscoveryMixIn
The convert_parameters(self, params) method orchestrates a six-step transformation process. According to the source code in [avocado_vt/discovery.py](https://github.com/avocado-framework/avocado-vt/blob/master/avocado_vt/discovery.py), the method begins at line 41 and handles the conversion through several distinct phases.
Step 1: Receiving Raw Cartesian Parameters
The method accepts a params dictionary containing every key-value pair parsed from the Cartesian configuration matrix. This includes test-specific parameters like mem, nettype, and image_format, alongside metadata keys such as _short_name_map_file that track the configuration's origin.
# Example input from the Cartesian parser
cartesian_params = {
"_short_name_map_file": {"subtests.cfg": "tests/linux/boot"},
"mem": "2048",
"nettype": "bridge",
"image_format": "qcow2"
}
Step 2: Resolving the Test Identifier
The mixin determines the canonical test name through a hierarchical resolution strategy defined in lines 49-58. By default, the test name is extracted from params["_short_name_map_file"]["subtests.cfg"] as implemented at lines 49-50.
However, the method supports two override mechanisms. First, if the user provides a vt-config file and sets the option vt.short_names_when_config to true, the name is taken from the shortname key in the Cartesian dictionary (lines 50-53). Second, for the spice backend specifically—detected when vt.type equals "spice"—the mixin checks for an alternative key tests-variants.cfg in the short name map (lines 54-58).
# Default resolution
test_name = params.get("_short_name_map_file")["subtests.cfg"]
# Override with shortname if config flags are set
if get_opt(self.config, "vt.config") and get_opt(self.config, "vt.short_names_when_config"):
test_name = params.get("shortname")
# Spice backend handling
elif get_opt(self.config, "vt.type") == "spice":
short_name_map_file = params.get("_short_name_map_file")
if short_name_map_file.get("tests-variants.cfg"):
test_name = short_name_map_file["tests-variants.cfg"]
Step 3: Enriching and Wrapping Parameters
Once resolved, the test identifier is injected back into the parameter dictionary at line 62 via params["id"] = test_name. This enrichment allows test code to reference its own identifier during execution. Finally, the method returns a structured dictionary at lines 63-64 containing two keys: name (the URI used by the runner) and vt_params (the original Cartesian dictionary now containing the id field).
params["id"] = test_name
test_parameters = {"name": test_name, "vt_params": params}
return test_parameters
From Parameters to Runnable: Integration Points
The output of convert_parameters() serves as the input for two critical integration points within Avocado-VT. The VTResolverUtils class in [avocado_vt/plugins/vt_resolver.py](https://github.com/avocado-framework/avocado-vt/blob/master/avocado_vt/plugins/vt_resolver.py) converts these parameters into a Runnable object. Specifically, the _parameters_to_runnable method (lines 20-31) instantiates avocado.core.nrunner.Runnable with the kind "avocado-vt", the URI from the name field, and the vt_params dictionary unpacked as keyword arguments.
Simultaneously, the AVocadoVTLoader in [avocado_vt/loader.py](https://github.com/avocado-framework/avocado-vt/blob/master/avocado_vt/loader.py) utilizes the same conversion method when building test suites for the classic runner. At lines 94-96, the loader constructs tuples of (VirtTest, self.convert_parameters(params)) to generate the final test suite list.
Practical Implementation Example
The following example demonstrates the complete conversion flow using actual source patterns:
from avocado_vt.discovery import DiscoveryMixIn
from avocado.core.settings import settings
# Initialize with Avocado configuration
config = settings.as_dict()
mixin = DiscoveryMixIn(config)
# Simulate Cartesian parser output
cartesian_dict = {
"_short_name_map_file": {"subtests.cfg": "io.netperf.tcp_stream"},
"netperf_client": "localhost",
"netperf_server": "guest",
"test_iterations": "5"
}
# Convert to Avocado-compatible parameters
result = mixin.convert_parameters(cartesian_dict)
print(result["name"])
# Output: io.netperf.tcp_stream
print(result["vt_params"]["id"])
# Output: io.netperf.tcp_stream
print(result["vt_params"]["netperf_client"])
# Output: localhost
When passed through the resolver, this becomes a executable Runnable:
from avocado.core.nrunner import Runnable
runnable = Runnable(
"avocado-vt",
result["name"],
**result["vt_params"]
)
# runnable.uri == "io.netperf.tcp_stream"
# runnable.kwargs contains the full VT configuration including 'id'
Summary
- DiscoveryMixIn serves as the architectural boundary between Cartesian configuration matrices and Avocado's test execution API.
- The test identifier resolution follows a priority order: default
subtests.cfgentry, optionalshortnameoverride whenvt.short_names_when_configis enabled, and special handling for the spice backend usingtests-variants.cfg. - The method enriches the original parameter dictionary by injecting the resolved identifier into the
idkey, then wraps it with the test name for URI generation. - The output is consumed by both the VTResolverUtils (for nrunner compatibility) and the AVocadoVTLoader (for classic runner compatibility), demonstrating the mixin's central role in the discovery pipeline.
Frequently Asked Questions
What is the purpose of the _short_name_map_file key in Cartesian configs?
The _short_name_map_file key is a metadata dictionary injected by the Cartesian parser that maps configuration file names to their corresponding short test identifiers. DiscoveryMixIn uses this map to extract the default test name from the subtests.cfg entry, providing a stable identifier derived from the configuration hierarchy rather than arbitrary parameter values.
How does DiscoveryMixIn handle different backend types like spice?
The mixin implements backend-aware naming through a conditional check at lines 54-58. When vt.type is configured as "spice", the method looks for an alternative key tests-variants.cfg within the _short_name_map_file dictionary. This allows the spice backend to use its specific naming conventions while maintaining compatibility with the standard qemu backend resolution logic.
What is the difference between the name and vt_params keys in the output dictionary?
The name key contains the resolved test identifier as a string, which serves as the URI for the Avocado runner to locate and execute the test. The vt_params key contains the complete, enriched Cartesian dictionary including all original parameters plus the injected id field. This separation allows the runner to use the URI for scheduling while passing the full configuration context to the test instance.
Which Avocado-VT components consume the output of convert_parameters?
The output is consumed by two primary components: VTResolverUtils in plugins/vt_resolver.py converts the dictionary into a Runnable object for the Avocado nrunner architecture, and AVocadoVTLoader in loader.py uses it to build test suite tuples for the classic runner. Both components rely on the standardized output format to bridge Cartesian configuration with Avocado's execution models.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →