Skip to content

Commit b256f5c

Browse files
authored
test migration with required HT feature and qemu 10.2.2 (#2378)
Signed-off-by: Maksim Fedotov <maksim.fedotov@flant.com>
1 parent 97f401c commit b256f5c

2 files changed

Lines changed: 97 additions & 5 deletions

File tree

images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const (
5050

5151
// GenericCPUModel specifies the base CPU model for Features and Discovery CPU model types.
5252
GenericCPUModel = "qemu64"
53+
HTCPUFeature = "ht"
5354

5455
MaxMemorySizeForHotplug = 256 * 1024 * 1024 * 1024 // 256 Gi (safely limit to not overlap somewhat conservative 38 bit physical address space)
5556
EnableMemoryHotplugThreshold = 1 * 1024 * 1024 * 1024 // 1 Gi (no hotplug for VMs with less than 1Gi)
@@ -162,27 +163,34 @@ func (b *KVVM) SetCPUModel(class *v1alpha2.VirtualMachineClass) error {
162163
cpu.Model = virtv1.CPUModeHostPassthrough
163164
case v1alpha2.CPUTypeModel:
164165
cpu.Model = class.Spec.CPU.Model
166+
cpu.Features = []virtv1.CPUFeature{{Name: HTCPUFeature, Policy: "optional"}}
165167
case v1alpha2.CPUTypeDiscovery, v1alpha2.CPUTypeFeatures:
166168
cpu.Model = GenericCPUModel
167-
l := len(class.Status.CpuFeatures.Enabled)
168-
features := make([]virtv1.CPUFeature, l, l+1)
169+
features := make([]virtv1.CPUFeature, 0, len(class.Status.CpuFeatures.Enabled)+2)
169170
hasSvm := false
170-
for i, feature := range class.Status.CpuFeatures.Enabled {
171+
hasHT := false
172+
for _, feature := range class.Status.CpuFeatures.Enabled {
171173
policy := "require"
172174
if feature == "invtsc" {
173175
policy = "optional"
174176
}
175177
if feature == "svm" {
176178
hasSvm = true
177179
}
178-
features[i] = virtv1.CPUFeature{
180+
if feature == HTCPUFeature {
181+
hasHT = true
182+
}
183+
features = append(features, virtv1.CPUFeature{
179184
Name: feature,
180185
Policy: policy,
181-
}
186+
})
182187
}
183188
if !hasSvm {
184189
features = append(features, virtv1.CPUFeature{Name: "svm", Policy: "optional"})
185190
}
191+
if !hasHT {
192+
features = append(features, virtv1.CPUFeature{Name: HTCPUFeature, Policy: "optional"})
193+
}
186194
cpu.Features = features
187195
default:
188196
return fmt.Errorf("unexpected cpu type: %q", class.Spec.CPU.Type)

images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
corev1 "k8s.io/api/core/v1"
2424
"k8s.io/apimachinery/pkg/types"
25+
virtv1 "kubevirt.io/api/core/v1"
2526

2627
"github.com/deckhouse/virtualization/api/core/v1alpha2"
2728
)
@@ -224,6 +225,89 @@ func TestApplyPVNodeAffinity(t *testing.T) {
224225
})
225226
}
226227

228+
func TestSetCPUModel(t *testing.T) {
229+
name := "test-name"
230+
namespace := "test-namespace"
231+
232+
t.Run("should add required ht feature for model cpu", func(t *testing.T) {
233+
builder := NewEmptyKVVM(types.NamespacedName{Name: name, Namespace: namespace}, KVVMOptions{})
234+
class := &v1alpha2.VirtualMachineClass{
235+
Spec: v1alpha2.VirtualMachineClassSpec{
236+
CPU: v1alpha2.CPU{Type: v1alpha2.CPUTypeModel, Model: "Nehalem"},
237+
},
238+
}
239+
240+
if err := builder.SetCPUModel(class); err != nil {
241+
t.Fatalf("SetCPUModel() failed: %v", err)
242+
}
243+
244+
features := builder.Resource.Spec.Template.Spec.Domain.CPU.Features
245+
if !containsCPUFeature(features, virtv1.CPUFeature{Name: HTCPUFeature, Policy: "optional"}) {
246+
t.Fatalf("expected optional ht feature to be added for model cpu, got %#v", features)
247+
}
248+
})
249+
250+
t.Run("should add required ht feature for discovery cpu", func(t *testing.T) {
251+
builder := NewEmptyKVVM(types.NamespacedName{Name: name, Namespace: namespace}, KVVMOptions{})
252+
class := &v1alpha2.VirtualMachineClass{
253+
Spec: v1alpha2.VirtualMachineClassSpec{
254+
CPU: v1alpha2.CPU{Type: v1alpha2.CPUTypeDiscovery},
255+
},
256+
Status: v1alpha2.VirtualMachineClassStatus{
257+
CpuFeatures: v1alpha2.CpuFeatures{Enabled: []string{"aes"}},
258+
},
259+
}
260+
261+
if err := builder.SetCPUModel(class); err != nil {
262+
t.Fatalf("SetCPUModel() failed: %v", err)
263+
}
264+
265+
features := builder.Resource.Spec.Template.Spec.Domain.CPU.Features
266+
if !containsCPUFeature(features, virtv1.CPUFeature{Name: HTCPUFeature, Policy: "require"}) {
267+
t.Fatalf("expected required ht feature to be added, got %#v", features)
268+
}
269+
})
270+
271+
t.Run("should keep existing ht feature policy when already present", func(t *testing.T) {
272+
builder := NewEmptyKVVM(types.NamespacedName{Name: name, Namespace: namespace}, KVVMOptions{})
273+
class := &v1alpha2.VirtualMachineClass{
274+
Spec: v1alpha2.VirtualMachineClassSpec{
275+
CPU: v1alpha2.CPU{Type: v1alpha2.CPUTypeFeatures},
276+
},
277+
Status: v1alpha2.VirtualMachineClassStatus{
278+
CpuFeatures: v1alpha2.CpuFeatures{Enabled: []string{"vmx", HTCPUFeature}},
279+
},
280+
}
281+
282+
if err := builder.SetCPUModel(class); err != nil {
283+
t.Fatalf("SetCPUModel() failed: %v", err)
284+
}
285+
286+
features := builder.Resource.Spec.Template.Spec.Domain.CPU.Features
287+
htCount := 0
288+
for _, feature := range features {
289+
if feature.Name == HTCPUFeature {
290+
htCount++
291+
if feature.Policy != "require" {
292+
t.Fatalf("expected existing ht policy to stay require, got %#v", feature)
293+
}
294+
}
295+
}
296+
if htCount != 1 {
297+
t.Fatalf("expected exactly one ht feature, got %#v", features)
298+
}
299+
})
300+
}
301+
302+
func containsCPUFeature(features []virtv1.CPUFeature, expected virtv1.CPUFeature) bool {
303+
for _, feature := range features {
304+
if feature == expected {
305+
return true
306+
}
307+
}
308+
return false
309+
}
310+
227311
func TestSetOsType(t *testing.T) {
228312
name := "test-name"
229313
namespace := "test-namespace"

0 commit comments

Comments
 (0)