Skip to content

Commit ef8192d

Browse files
committed
refactor(kubevirt): Extract common VM test verification logic to shared helpers
Extract common verification patterns from VM test tasks into a shared helper library to improve code reuse, maintainability, and consistency. Changes: - Create shared verification helper library in tests/helpers/ - verify-vm.sh: 8 reusable verification functions with flexible matching - README.md: Comprehensive documentation with usage examples - Refactor all VM test tasks to use shared helpers: - create-vm-basic: 43 → 33 lines (~23% reduction) - create-vm-ubuntu: 43 → 33 lines (~23% reduction) - create-vm-with-size: 62 → 39 lines (~37% reduction) - create-vm-with-instancetype: 59 → 39 lines (~34% reduction) - create-vm-with-performance: 72 → 45 lines (~38% reduction) Helper Functions: - verify_vm_exists: Wait for VM creation - verify_container_disk: Verify OS container disk (checks all volumes) - verify_run_strategy: Check runStrategy (accepts spec or status) - verify_instancetype: Verify instancetype with optional exact match - verify_instancetype_contains: Check instancetype contains substring - verify_instancetype_prefix: Check instancetype starts with prefix - verify_no_direct_resources: Verify VM uses instancetype - verify_has_resources_or_instancetype: Verify either instancetype or resources Bug Fixes: - Fix volume name verification to check all volumes instead of specific names (handles different VM creation approaches) - Fix runStrategy verification to accept both spec.runStrategy and status.runStrategy (handles deprecated 'running' field) Benefits: - Eliminated ~150 lines of duplicated verification code - Single source of truth for verification logic - More maintainable and easier to extend - Consistent error messages and output formatting - Tests are more concise and readable Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
1 parent d3c5fdd commit ef8192d

File tree

7 files changed

+414
-203
lines changed

7 files changed

+414
-203
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Test Verification Helpers
2+
3+
This directory contains shared helper functions for VirtualMachine test verification.
4+
5+
## Usage
6+
7+
Source the helper script in your test verification section:
8+
9+
```bash
10+
#!/usr/bin/env bash
11+
source "$(dirname "${BASH_SOURCE[0]}")/../../helpers/verify-vm.sh"
12+
13+
# Use helper functions
14+
verify_vm_exists "test-vm" "vm-test" || exit 1
15+
verify_container_disk "test-vm" "vm-test" "fedora" || exit 1
16+
verify_run_strategy "test-vm" "vm-test" || exit 1
17+
```
18+
19+
## Available Functions
20+
21+
### verify_vm_exists
22+
Waits for a VirtualMachine to be created.
23+
24+
**Usage:** `verify_vm_exists <vm-name> <namespace> [timeout]`
25+
26+
**Example:**
27+
```bash
28+
verify_vm_exists "my-vm" "vm-test" "30s" || exit 1
29+
```
30+
31+
**Default timeout:** 30s
32+
33+
---
34+
35+
### verify_container_disk
36+
Verifies that a VM uses a specific container disk OS (checks all volumes).
37+
38+
**Usage:** `verify_container_disk <vm-name> <namespace> <os-name>`
39+
40+
**Example:**
41+
```bash
42+
verify_container_disk "my-vm" "vm-test" "fedora" || exit 1
43+
verify_container_disk "ubuntu-vm" "vm-test" "ubuntu" || exit 1
44+
```
45+
46+
---
47+
48+
### verify_run_strategy
49+
Verifies that runStrategy is set (checks both spec and status).
50+
51+
**Usage:** `verify_run_strategy <vm-name> <namespace>`
52+
53+
**Example:**
54+
```bash
55+
verify_run_strategy "my-vm" "vm-test" || exit 1
56+
```
57+
58+
**Note:** This function accepts runStrategy in either `spec.runStrategy` or `status.runStrategy` to accommodate VMs created with the deprecated `running` field.
59+
60+
---
61+
62+
### verify_instancetype
63+
Verifies that a VM has an instancetype reference with optional exact match.
64+
65+
**Usage:** `verify_instancetype <vm-name> <namespace> [expected-instancetype] [expected-kind]`
66+
67+
**Examples:**
68+
```bash
69+
# Just verify instancetype exists
70+
verify_instancetype "my-vm" "vm-test" || exit 1
71+
72+
# Verify specific instancetype
73+
verify_instancetype "my-vm" "vm-test" "u1.medium" || exit 1
74+
75+
# Verify instancetype and kind
76+
verify_instancetype "my-vm" "vm-test" "u1.medium" "VirtualMachineClusterInstancetype" || exit 1
77+
```
78+
79+
**Default kind:** VirtualMachineClusterInstancetype
80+
81+
---
82+
83+
### verify_instancetype_contains
84+
Verifies that instancetype name contains a substring (e.g., size like "large").
85+
86+
**Usage:** `verify_instancetype_contains <vm-name> <namespace> <substring> [description]`
87+
88+
**Example:**
89+
```bash
90+
verify_instancetype_contains "my-vm" "vm-test" "large" "requested size 'large'"
91+
verify_instancetype_contains "my-vm" "vm-test" "medium"
92+
```
93+
94+
**Note:** Returns success even if substring not found (prints warning only).
95+
96+
---
97+
98+
### verify_instancetype_prefix
99+
Verifies that instancetype starts with a specific prefix (e.g., performance family like "c1").
100+
101+
**Usage:** `verify_instancetype_prefix <vm-name> <namespace> <prefix> [description]`
102+
103+
**Example:**
104+
```bash
105+
verify_instancetype_prefix "my-vm" "vm-test" "c1" "compute-optimized"
106+
verify_instancetype_prefix "my-vm" "vm-test" "u1" "general-purpose"
107+
```
108+
109+
**Note:** Returns success even if prefix doesn't match (prints warning only).
110+
111+
---
112+
113+
### verify_no_direct_resources
114+
Verifies that VM uses instancetype for resources (no direct memory specification).
115+
116+
**Usage:** `verify_no_direct_resources <vm-name> <namespace>`
117+
118+
**Example:**
119+
```bash
120+
verify_no_direct_resources "my-vm" "vm-test"
121+
```
122+
123+
**Note:** Returns success even if direct resources found (prints warning only).
124+
125+
---
126+
127+
### verify_has_resources_or_instancetype
128+
Verifies that VM has either an instancetype or direct resource specification.
129+
130+
**Usage:** `verify_has_resources_or_instancetype <vm-name> <namespace>`
131+
132+
**Example:**
133+
```bash
134+
verify_has_resources_or_instancetype "my-vm" "vm-test" || exit 1
135+
```
136+
137+
**Note:** Fails only if neither instancetype nor direct resources are present.
138+
139+
## Design Principles
140+
141+
1. **Flexible matching**: Functions use pattern matching instead of exact volume names to handle different VM creation approaches.
142+
143+
2. **Clear output**: Each function prints clear success (✓) or failure (✗) messages.
144+
145+
3. **Warning vs Error**: Some functions print warnings (⚠) for non-critical mismatches but still return success.
146+
147+
4. **Return codes**: Functions return 0 for success, 1 for failure. Always check return codes with `|| exit 1` for critical validations.
148+
149+
## Example Test Verification
150+
151+
```bash
152+
#!/usr/bin/env bash
153+
source "$(dirname "${BASH_SOURCE[0]}")/../../helpers/verify-vm.sh"
154+
155+
# Wait for VM to exist
156+
verify_vm_exists "test-vm" "vm-test" || exit 1
157+
158+
# Verify container disk
159+
verify_container_disk "test-vm" "vm-test" "fedora" || exit 1
160+
161+
# Verify runStrategy
162+
verify_run_strategy "test-vm" "vm-test" || exit 1
163+
164+
# Verify instancetype with size
165+
verify_instancetype "test-vm" "vm-test" || exit 1
166+
verify_instancetype_contains "test-vm" "vm-test" "large"
167+
168+
# Verify no direct resources
169+
verify_no_direct_resources "test-vm" "vm-test"
170+
171+
echo "All validations passed"
172+
exit 0
173+
```
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
#!/usr/bin/env bash
2+
# Shared verification helper functions for VirtualMachine tests
3+
4+
# verify_vm_exists: Waits for a VirtualMachine to be created
5+
# Usage: verify_vm_exists <vm-name> <namespace> [timeout]
6+
verify_vm_exists() {
7+
local vm_name="$1"
8+
local namespace="$2"
9+
local timeout="${3:-30s}"
10+
11+
if ! kubectl wait --for=jsonpath='{.metadata.name}'="$vm_name" virtualmachine/"$vm_name" -n "$namespace" --timeout="$timeout" 2>/dev/null; then
12+
echo "VirtualMachine $vm_name not found in namespace $namespace"
13+
kubectl get virtualmachines -n "$namespace"
14+
return 1
15+
fi
16+
echo "VirtualMachine $vm_name created successfully"
17+
return 0
18+
}
19+
20+
# verify_container_disk: Verifies that a VM uses a specific container disk OS
21+
# Usage: verify_container_disk <vm-name> <namespace> <os-name>
22+
# Example: verify_container_disk test-vm vm-test fedora
23+
verify_container_disk() {
24+
local vm_name="$1"
25+
local namespace="$2"
26+
local os_name="$3"
27+
28+
# Get all container disk images from all volumes
29+
local container_disks
30+
container_disks=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.template.spec.volumes[*].containerDisk.image}')
31+
32+
if [[ "$container_disks" =~ $os_name ]]; then
33+
echo "✓ VirtualMachine uses $os_name container disk"
34+
return 0
35+
else
36+
echo "✗ Expected $os_name container disk, found volumes with images: $container_disks"
37+
kubectl get virtualmachine "$vm_name" -n "$namespace" -o yaml
38+
return 1
39+
fi
40+
}
41+
42+
# verify_run_strategy: Verifies that runStrategy is set (in spec or status)
43+
# Usage: verify_run_strategy <vm-name> <namespace>
44+
verify_run_strategy() {
45+
local vm_name="$1"
46+
local namespace="$2"
47+
48+
local spec_run_strategy
49+
local status_run_strategy
50+
spec_run_strategy=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.runStrategy}')
51+
status_run_strategy=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.status.runStrategy}')
52+
53+
if [[ -n "$spec_run_strategy" ]]; then
54+
echo "✓ VirtualMachine uses runStrategy in spec: $spec_run_strategy"
55+
return 0
56+
elif [[ -n "$status_run_strategy" ]]; then
57+
echo "✓ VirtualMachine has runStrategy in status: $status_run_strategy"
58+
echo " Note: VM may have been created with deprecated 'running' field, but runStrategy is set in status"
59+
return 0
60+
else
61+
echo "✗ VirtualMachine missing runStrategy field in both spec and status"
62+
return 1
63+
fi
64+
}
65+
66+
# verify_instancetype: Verifies that a VM has an instancetype reference
67+
# Usage: verify_instancetype <vm-name> <namespace> [expected-instancetype] [expected-kind]
68+
verify_instancetype() {
69+
local vm_name="$1"
70+
local namespace="$2"
71+
local expected_instancetype="$3"
72+
local expected_kind="${4:-VirtualMachineClusterInstancetype}"
73+
74+
local instancetype
75+
instancetype=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.instancetype.name}')
76+
77+
if [[ -z "$instancetype" ]]; then
78+
echo "✗ VirtualMachine has no instancetype reference"
79+
return 1
80+
fi
81+
82+
echo "✓ VirtualMachine has instancetype reference: $instancetype"
83+
84+
# Check expected instancetype if provided
85+
if [[ -n "$expected_instancetype" ]]; then
86+
if [[ "$instancetype" == "$expected_instancetype" ]]; then
87+
echo "✓ Instancetype matches expected value: $expected_instancetype"
88+
else
89+
echo "✗ Expected instancetype '$expected_instancetype', found: $instancetype"
90+
return 1
91+
fi
92+
fi
93+
94+
# Verify instancetype kind
95+
local instancetype_kind
96+
instancetype_kind=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.instancetype.kind}')
97+
if [[ "$instancetype_kind" == "$expected_kind" ]]; then
98+
echo "✓ Instancetype kind is $expected_kind"
99+
else
100+
echo "⚠ Instancetype kind is: $instancetype_kind (expected: $expected_kind)"
101+
fi
102+
103+
return 0
104+
}
105+
106+
# verify_instancetype_contains: Verifies that instancetype name contains a string
107+
# Usage: verify_instancetype_contains <vm-name> <namespace> <substring> [description]
108+
verify_instancetype_contains() {
109+
local vm_name="$1"
110+
local namespace="$2"
111+
local substring="$3"
112+
local description="${4:-$substring}"
113+
114+
local instancetype
115+
instancetype=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.instancetype.name}')
116+
117+
if [[ -z "$instancetype" ]]; then
118+
echo "✗ VirtualMachine has no instancetype reference"
119+
return 1
120+
fi
121+
122+
if [[ "$instancetype" =~ $substring ]]; then
123+
echo "✓ Instancetype matches $description: $instancetype"
124+
return 0
125+
else
126+
echo "⚠ Instancetype '$instancetype' doesn't match $description"
127+
return 0 # Return success for warnings
128+
fi
129+
}
130+
131+
# verify_instancetype_prefix: Verifies that instancetype starts with a prefix
132+
# Usage: verify_instancetype_prefix <vm-name> <namespace> <prefix> [description]
133+
verify_instancetype_prefix() {
134+
local vm_name="$1"
135+
local namespace="$2"
136+
local prefix="$3"
137+
local description="${4:-$prefix}"
138+
139+
local instancetype
140+
instancetype=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.instancetype.name}')
141+
142+
if [[ -z "$instancetype" ]]; then
143+
echo "✗ VirtualMachine has no instancetype reference"
144+
return 1
145+
fi
146+
147+
if [[ "$instancetype" =~ ^${prefix}\. ]]; then
148+
echo "✓ Instancetype matches $description family: $instancetype"
149+
return 0
150+
else
151+
echo "⚠ Instancetype '$instancetype' doesn't start with '$prefix'"
152+
return 0 # Return success for warnings
153+
fi
154+
}
155+
156+
# verify_no_direct_resources: Verifies VM uses instancetype (no direct memory spec)
157+
# Usage: verify_no_direct_resources <vm-name> <namespace>
158+
verify_no_direct_resources() {
159+
local vm_name="$1"
160+
local namespace="$2"
161+
162+
local guest_memory
163+
guest_memory=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.template.spec.domain.memory.guest}')
164+
165+
if [[ -z "$guest_memory" ]]; then
166+
echo "✓ VirtualMachine uses instancetype for resources (no direct memory spec)"
167+
return 0
168+
else
169+
echo "⚠ VirtualMachine has direct memory specification: $guest_memory"
170+
return 0 # Return success for warnings
171+
fi
172+
}
173+
174+
# verify_has_resources_or_instancetype: Verifies VM has either instancetype or direct resources
175+
# Usage: verify_has_resources_or_instancetype <vm-name> <namespace>
176+
verify_has_resources_or_instancetype() {
177+
local vm_name="$1"
178+
local namespace="$2"
179+
180+
local instancetype
181+
instancetype=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.instancetype.name}')
182+
183+
if [[ -n "$instancetype" ]]; then
184+
echo "✓ VirtualMachine has instancetype reference: $instancetype"
185+
return 0
186+
fi
187+
188+
# Check for direct resource specification
189+
local guest_memory
190+
guest_memory=$(kubectl get virtualmachine "$vm_name" -n "$namespace" -o jsonpath='{.spec.template.spec.domain.memory.guest}')
191+
192+
if [[ -n "$guest_memory" ]]; then
193+
echo "⚠ No instancetype set, but VM has direct memory specification: $guest_memory"
194+
return 0
195+
else
196+
echo "✗ VirtualMachine has no instancetype and no direct resource specification"
197+
kubectl get virtualmachine "$vm_name" -n "$namespace" -o yaml
198+
return 1
199+
fi
200+
}

0 commit comments

Comments
 (0)