# How VirtTestOptionsProcess Handles VT-Specific Command-Line Options in Avocado-VT

> Learn how VirtTestOptionsProcess in Avocado VT processes VT-specific command-line options like --vt-type and --vt-qemu-bin, merging them with settings for a coherent configuration.

- Repository: [avocado/avocado-vt](https://github.com/avocado-framework/avocado-vt)
- Tags: how-to-guide
- Published: 2026-02-25

---

**The VirtTestOptionsProcess class in [`avocado_vt/options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/options.py) translates VT-specific command-line flags like `--vt-type` and `--vt-qemu-bin` into a cartesian configuration by registering options, merging them with settings files, and applying precedence rules where configuration files override CLI arguments.**

The `avocado-framework/avocado-vt` repository provides the Virt Test (VT) plugin for Avocado, enabling automated virtualization testing across QEMU, libvirt, and other backends. At the heart of this system lies the **VirtTestOptionsProcess** class defined in [`avocado_vt/options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/options.py), which serves as the bridge between user-supplied command-line arguments and the internal cartesian test matrix used by the virt-test framework.

## The Three-Stage Processing Pipeline

The VirtTestOptionsProcess operates through a deterministic three-stage pipeline that transforms raw CLI input into a structured test configuration.

### Stage 1: Option Registration in the VT Plugin

Before any parsing occurs, the VT plugin registers all VT-specific flags with Avocado's argument parser. In [`avocado_vt/plugins/vt.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/plugins/vt.py), the functions `add_basic_vt_options` and `add_qemu_bin_vt_option` attach flags such as `--vt-type`, `--vt-arch`, `--vt-guest-os`, and `--vt-qemu-bin` to the `run` sub-parser.

Each registration maps the CLI flag to a configuration key under the `vt.*` namespace. For example, `--vt-type qemu` populates `config['vt.type'] = 'qemu'`. The QEMU binary option includes auto-detection logic that defaults to the system QEMU installation if no explicit path is provided.

### Stage 2: Configuration Loading and Merging

When `avocado run` executes, the VirtTestOptionsProcess initializes with a `Config` object containing values from multiple sources. The `__init__` method in [`avocado_vt/options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/options.py) (lines 43-66) orchestrates this merge:

1. **CLI arguments** override any defaults
2. **Settings files** (`conf.d/*.conf`) are loaded via `set_opt_from_settings`, copying `vt.*` entries into the Config object
3. **Built-in defaults** apply when neither CLI nor settings provide a value

This layered approach ensures that environment-specific defaults can persist in configuration files while allowing one-off CLI overrides for ad-hoc test runs.

### Stage 3: Cartesian Parser Translation

The final stage converts the merged configuration into a cartesian test matrix. The `_process_options` method creates a fresh `cartesian_config.Parser` instance and delegates to specialized private methods for each option family:

- `_process_qemu_bin` handles `--vt-qemu-bin` and auto-discovery via `standalone_test.find_default_qemu_paths`
- `_process_bridge_mode` validates `nettype` against `SUPPORTED_NET_TYPES` and applies bridge or user networking defaults based on UID
- `_process_monitor` configures QEMU monitor settings
- `_process_smp` translates CPU count into cartesian filters

Each helper follows strict precedence rules: if `vt.config` (a configuration file) is specified, most CLI options are ignored with a logged message, as the config file is considered authoritative. Otherwise, the explicit CLI value or settings file value is assigned to the cartesian parser using `assign`, `only_filter`, or `no_filter` calls.

## Key Processing Methods and Precedence Rules

Understanding the internal methods of VirtTestOptionsProcess reveals how the system handles edge cases and conflicting inputs.

### Configuration File vs. Command-Line Precedence

The `_process_*` methods consistently implement a precedence hierarchy:

1. **Configuration file (`--vt-config`)** takes absolute precedence. When present, the method logs `LOG.info("Config provided, ignoring %s", option_name)` and skips CLI processing for that option.
2. **Explicit CLI flags** override settings file values when no config file is used.
3. **Settings files** (`conf.d/*.conf`) provide defaults when neither CLI nor config file specifies a value.
4. **Hardcoded defaults** apply as final fallbacks.

This hierarchy ensures reproducible test runs: a configuration file captures the complete environment state, while CLI flags allow quick iterations during development.

### Backend-Specific Processing

The `_process_backend_specific_options` method dispatches to specialized handlers based on `vt.type`:

- **QEMU**: Invokes `_process_qemu_bin`, `_process_smp`, and other QEMU-specific routines defined in [`options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/options.py)
- **LVSB** (Linux Virtual Server Base): Uses a simplified processing path that skips general options
- **libvirt**: Applies libvirt-specific configuration mappings
- **spice**: Handles SPICE protocol-specific settings

Each backend can inject its own defaults. For example, QEMU processing automatically detects binary paths via [`virttest/standalone_test.py`](https://github.com/avocado-framework/avocado-vt/blob/main/virttest/standalone_test.py)'s `find_default_qemu_paths` function when the user does not specify `--vt-qemu-bin` and no config file is present.

## Practical Examples

### Running a VT Test from the Command Line

```bash

# Basic QEMU test on x86_64 with a custom QEMU binary

avocado run my_test.py \
    --vt-type qemu \
    --vt-arch x86_64 \
    --vt-qemu-bin /usr/local/bin/qemu-system-x86_64 \
    --vt-smp 4 \
    --vt-no-filter "no_9p_export"

```

*Explanation*:  
* `--vt-type` selects the backend (`qemu`).  
* `--vt-arch` forces the cartesian parser to filter on the `x86_64` architecture.  
* `--vt-qemu-bin` overrides the auto-detected binary; the path is stored in the cartesian parser as `qemu_binary`.  
* `--vt-smp 4` triggers `_process_smp`, which adds the `smp2` filter for the default case and, because the value is not `1` or `2`, it assigns `smp = 4`.  
* `--vt-no-filter` removes the `no_9p_export` filter from the default test matrix.

### Using a Configuration File (Overrides CLI Flags)

[`my_vt.cfg`](https://github.com/avocado-framework/avocado-vt/blob/main/my_vt.cfg) (placed in the current directory or pointed by `--vt-config`):

```ini
vt.type = qemu
vt.common.arch = aarch64
vt.qemu.qemu_bin = /opt/qemu/bin/qemu-system-aarch64
vt.qemu.smp = 2

```

Run:

```bash
avocado run my_test.py --vt-config my_vt.cfg --vt-arch x86_64

```

*Result*: The `--vt-arch` flag is **ignored** because a config file is present; the parser uses `aarch64` from the file. This is logged by the `_process_arch` routine (`LOG.info("Config provided, ignoring %s", arch_setting)`).

### Programmatic Use (Python)

```python
from avocado.core import config
from avocado_vt.options import VirtTestOptionsProcess

# Build an Avocado config manually

cfg = config.Config()
cfg['vt.type'] = 'qemu'
cfg['vt.qemu.smp'] = '4'   # emulate a 4-CPU VM

cfg['vt.common.nettype'] = 'bridge'

opts = VirtTestOptionsProcess(cfg)
parser = opts.get_parser()          # ← fully resolved cartesian parser

print(parser._cartesian)            # internal representation

```

The Python snippet shows how the same option-processing logic can be reused by other tools that need to generate the cartesian matrix without invoking the CLI.

## Summary

- **VirtTestOptionsProcess** in [`avocado_vt/options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/options.py) serves as the central translator between VT CLI flags and the cartesian test matrix.
- The workflow follows three stages: **option registration** in [`avocado_vt/plugins/vt.py`](https://github.com/avocado-framework/avocado-vt/blob/main/avocado_vt/plugins/vt.py), **configuration merging** during initialization, and **cartesian parser population** via specialized `_process_*` methods.
- **Precedence rules** strictly favor configuration files (`--vt-config`) over CLI flags, with settings files and hardcoded defaults as fallbacks.
- **Backend-specific handlers** dispatch processing based on `vt.type`, enabling tailored logic for QEMU, libvirt, LVSB, and SPICE test environments.
- The system supports both **CLI invocation** and **programmatic reuse** via direct Python instantiation of `VirtTestOptionsProcess`.

## Frequently Asked Questions

### What happens when both --vt-config and --vt-type are specified?

When a configuration file is provided via `--vt-config`, the `vt.type` value from that file takes precedence over the `--vt-type` CLI flag. The `_process_general_options` method checks for the presence of `vt.config` and logs that CLI flags are being ignored, ensuring the configuration file serves as the authoritative source for test parameters.

### How does VirtTestOptionsProcess determine the default QEMU binary?

If no `--vt-qemu-bin` flag is provided and no configuration file is specified, the `_process_qemu_bin` method calls `find_default_qemu_paths` from [`virttest/standalone_test.py`](https://github.com/avocado-framework/avocado-vt/blob/main/virttest/standalone_test.py). This helper searches standard system paths for `qemu-system-*` binaries and related tools (qemu-img, qemu-io), returning the discovered paths to be assigned to the cartesian parser as `qemu_binary`, `qemu_img_binary`, and `qemu_io_binary`.

### Can I use VirtTestOptionsProcess programmatically without the Avocado CLI?

Yes, you can instantiate `VirtTestOptionsProcess` directly with a manually constructed `Config` object. Import the class from `avocado_vt.options`, populate a configuration dictionary with keys like `vt.type`, `vt.qemu.smp`, and `vt.common.nettype`, then call `get_parser()` to receive a fully resolved cartesian parser. This enables custom tools to generate test matrices without invoking the `avocado run` command.

### What is the precedence order for VT configuration values?

The VirtTestOptionsProcess applies a strict four-level hierarchy: **Configuration file** (`--vt-config`) overrides all other sources; **Explicit CLI flags** (e.g., `--vt-arch`) override settings files and defaults when no config file is used; **Settings files** (`conf.d/*.conf`) provide defaults when neither CLI nor config file specifies a value; **Hardcoded defaults** apply as final fallbacks. This precedence is enforced consistently across all `_process_*` methods in [`options.py`](https://github.com/avocado-framework/avocado-vt/blob/main/options.py).