Operations & Chaos
Evaluate OpenShift Virtualization robustness under duress, execute disruptive component testing, and validate disaster recovery mechanics. Operations and chaos testing ensures your system gracefully handles data loss, ungraceful node restarts, disrupted storage paths, and pod terminations without permanently degrading workloads.
Prerequisites
- A running OpenShift cluster with OpenShift Virtualization deployed.
- OpenShift API for Data Protection (OADP) configured (if executing
data_protection/test cases). - Correct markers specified for execution:
@pytest.mark.chaosis required for standard disruption tests. - The
multiprocessing_start_method_forkfixture activated (usually viapytestmark) for suites relying on continuous background process failures.
Quick Example: Component Disruption
To verify that VirtualMachines can still be deployed and managed when control-plane pods are repeatedly deleted, utilize the parameterized pod_deleting_process indirect fixture.
import pytest
from ocp_resources.deployment import Deployment
from utilities.constants.namespaces import NamespacesNames
from utilities.constants.timeouts import TIMEOUT_5SEC, TIMEOUT_5MIN
from utilities.virt import running_vm
pytestmark = [
pytest.mark.chaos,
pytest.mark.usefixtures(
"multiprocessing_start_method_fork",
"chaos_namespace",
"cluster_monitoring_process"
),
]
@pytest.mark.parametrize(
"chaos_vms_list_rhel9, pod_deleting_process",
[
pytest.param(
{"number_of_vms": 3},
{
"pod_prefix": "apiserver",
"resource": Deployment,
"namespace_name": NamespacesNames.OPENSHIFT_APISERVER,
"ratio": 0.5,
"interval": TIMEOUT_5SEC,
"max_duration": TIMEOUT_5MIN,
},
)
],
indirect=True,
)
def test_pod_delete_openshift_apiserver(pod_deleting_process, chaos_vms_list_rhel9):
"""
Verifies that VMs can be deployed while openshift-apiserver pods are continuously deleted.
"""
for vm in chaos_vms_list_rhel9:
vm.deploy()
running_vm(vm=vm, wait_for_interfaces=False, check_ssh_connectivity=False)
Note: The
pod_deleting_processfixture initiates a background process that consistently deletes a defined ratio (e.g.,0.5or 50%) of the target pods at a set interval while your test logic executes.
Implementing Chaos Experiments
When designing disruptive tests, the primary sequence is to introduce an active interference, perform a standard workload procedure (e.g., VM creation), and assert the system tolerated the disruption.
1. Select the Disruption Vector
The suite contains various disruption patterns. Use the utilities in tests/chaos/utils.py to trigger them:
- Process Manipulation: Call
create_pod_deleting_processorcreate_pod_deleting_threadto force restarts of critical operators or daemonsets. - Hardware and Node Interference: Yield the
rebooting_nodegenerator to suddenly restart cluster nodes where workloads reside.
2. Track System Degradation
Add cluster_monitoring_process (scoped at the module level in tests/chaos/conftest.py) to your test's usefixtures list. This parallel worker logs pod, daemonset, and node states out to a chaos-monitoring.txt log file so you can correlate system health with any test failures.
3. Assert Component Recovery
Always confirm the system heals after the disruption event finishes. Use pod_deleting_process_recover to poll deployments and daemonsets until they report full health and replica matching before passing the test.
Advanced Usage
Data Protection & Disaster Recovery (OADP)
The tests/data_protection/oadp/ directory evaluates snapshot, backup, and restore capabilities via Velero. The aim is to ensure workload data, such as database files within a VM, remains perfectly intact when restored.
import pytest
from ocp_resources.datavolume import DataVolume
from utilities.constants import Images
from utilities.oadp import check_file_in_running_vm
from utilities.constants.oadp import FILE_NAME_FOR_BACKUP, TEXT_TO_TEST
@pytest.mark.parametrize(
"rhel_vm_with_data_volume_template",
[
pytest.param(
{
"dv_name": "filesystem-dv",
"vm_name": "filesystem-vm",
"volume_mode": DataVolume.VolumeMode.FILE,
"rhel_image": Images.Rhel.RHEL9_3_IMG,
},
),
],
indirect=True,
)
@pytest.mark.usefixtures("velero_restore_first_namespace_with_datamover")
def test_backup_vm_data_volume_template_with_datamover(rhel_vm_with_data_volume_template):
# Validates the VM state was perfectly restored by Velero
check_file_in_running_vm(
vm=rhel_vm_with_data_volume_template,
file_name=FILE_NAME_FOR_BACKUP,
file_content=TEXT_TO_TEST
)
Key OADP Fixtures:
velero_backup_single_namespace: (Session scoped) Triggers a backup of a dedicated namespace, polling Velero until it confirms partial or full completion.velero_restore_first_namespace_with_datamover: (Module scoped) Restores resources using a CSI Datamover, yielding when workloads report completion.rhel_vm_with_data_volume_template: Seeds VMs with test data natively before a backup initiates.
Host IO & CPU Stressing
To validate performance boundaries, trigger host-level utilities like stress-ng using the chaos_worker_background_process parameterized fixture.
@pytest.mark.parametrize(
"chaos_worker_background_process",
[
pytest.param(
{
"max_duration": TIMEOUT_2MIN,
"background_command": "stress-ng --io 5 -t 120s",
"process_name": "stress-ng",
},
),
],
indirect=True,
)
def test_host_io_stress(
vm_with_nginx_service,
nginx_monitoring_process,
chaos_worker_background_process,
):
chaos_worker_background_process.join()
nginx_monitoring_process.join()
assert nginx_monitoring_process.exitcode == 0, "NGINX failed to respond under IO load"
assert chaos_worker_background_process.exitcode == 0, "Stress workload failed to execute"
Functions and Modules Summary
| Resource / Module | Path | Purpose |
|---|---|---|
| Disruption Utils | tests/chaos/utils.py |
Contains process threads (create_pod_deleting_thread), process killers, and node reboot handlers. |
| Chaos Standard | tests/chaos/standard/test_standard.py |
Standard experimental test flows asserting VM operation during pod starvation and component destruction. |
| OADP/Velero Workflows | tests/data_protection/oadp/test_velero.py |
Full-stack backup and CSI data-mover restore validation routines across file and block volume modes. |
| OADP Verification | utilities.oadp |
Utility operations specific to reading marker files off recovered VMs (check_file_in_running_vm). |
Tip: Do not write defensive polling loops (e.g. infinite retries waiting for an API response) when a failure condition is actively invoked. Use native timeout patterns, and if a workload action fails during chaos, the test should explicitly fail. See Resource Lifecycle & Validation for more on safe polling mechanics.