1 package api
2
3 import (
4 . "github.com/onsi/ginkgo/v2"
5 . "github.com/onsi/gomega"
6 "k8s.io/utils/pointer"
7
8 v1 "kubevirt.io/api/core/v1"
9 )
10
11 var _ = Describe("Defaults", func() {
12
13 It("should leave the scheduler name unset by default", func() {
14 vmi := &v1.VirtualMachineInstance{}
15 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
16 Expect(vmi.Spec.SchedulerName).To(BeEmpty())
17 })
18
19 It("should take a custom scheduler if specified", func() {
20 vmi := &v1.VirtualMachineInstance{Spec: v1.VirtualMachineInstanceSpec{SchedulerName: "custom-one"}}
21 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
22 Expect(vmi.Spec.SchedulerName).To(Equal("custom-one"))
23 })
24
25 It("should add ACPI feature if it is unspecified", func() {
26 vmi := &v1.VirtualMachineInstance{}
27 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
28 Expect(*vmi.Spec.Domain.Features.ACPI.Enabled).To(BeTrue())
29 })
30
31 It("should not add non-ACPI feature by default", func() {
32 vmi := &v1.VirtualMachineInstance{}
33 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
34 Expect(vmi.Spec.Domain.Features.APIC).To(BeNil())
35 Expect(vmi.Spec.Domain.Features.Hyperv).To(BeNil())
36 })
37
38 It("should not add SMM feature if it is unspecified", func() {
39 vmi := &v1.VirtualMachineInstance{}
40 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
41 Expect(vmi.Spec.Domain.Features.SMM).To(BeNil())
42 })
43
44 It("should add interface and pod network by default", func() {
45 vmi := &v1.VirtualMachineInstance{}
46 v1.SetDefaults_NetworkInterface(vmi)
47 Expect(vmi.Spec.Domain.Devices.Interfaces).NotTo(BeEmpty())
48 Expect(vmi.Spec.Networks).NotTo(BeEmpty())
49 })
50
51 It("should default to true to all defined features", func() {
52 vmi := &v1.VirtualMachineInstance{
53 Spec: v1.VirtualMachineInstanceSpec{
54 Domain: v1.DomainSpec{},
55 },
56 }
57 vmi.Spec.Domain.Features = &v1.Features{
58 ACPI: v1.FeatureState{},
59 SMM: &v1.FeatureState{},
60 APIC: &v1.FeatureAPIC{},
61 Hyperv: &v1.FeatureHyperv{
62 Relaxed: &v1.FeatureState{},
63 VAPIC: &v1.FeatureState{},
64 Spinlocks: &v1.FeatureSpinlocks{},
65 VPIndex: &v1.FeatureState{},
66 Runtime: &v1.FeatureState{},
67 SyNIC: &v1.FeatureState{},
68 SyNICTimer: &v1.SyNICTimer{},
69 Reset: &v1.FeatureState{},
70 VendorID: &v1.FeatureVendorID{},
71 Frequencies: &v1.FeatureState{},
72 Reenlightenment: &v1.FeatureState{},
73 TLBFlush: &v1.FeatureState{},
74 },
75 }
76 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
77
78 features := vmi.Spec.Domain.Features
79 hyperv := features.Hyperv
80
81 Expect(*features.ACPI.Enabled).To(BeTrue())
82 Expect(*features.SMM.Enabled).To(BeTrue())
83 Expect(*features.APIC.Enabled).To(BeTrue())
84 Expect(*hyperv.Relaxed.Enabled).To(BeTrue())
85 Expect(*hyperv.VAPIC.Enabled).To(BeTrue())
86 Expect(*hyperv.Spinlocks.Enabled).To(BeTrue())
87 Expect(*hyperv.Spinlocks.Retries).To(Equal(uint32(4096)))
88 Expect(*hyperv.VPIndex.Enabled).To(BeTrue())
89 Expect(*hyperv.Runtime.Enabled).To(BeTrue())
90 Expect(*hyperv.SyNIC.Enabled).To(BeTrue())
91 Expect(*hyperv.SyNICTimer.Enabled).To(BeTrue())
92 Expect(*hyperv.Reset.Enabled).To(BeTrue())
93 Expect(*hyperv.VendorID.Enabled).To(BeTrue())
94 Expect(*hyperv.Frequencies.Enabled).To(BeTrue())
95 Expect(*hyperv.Reenlightenment.Enabled).To(BeTrue())
96 Expect(*hyperv.TLBFlush.Enabled).To(BeTrue())
97 })
98
99 It("should not override defined feature states", func() {
100 vmi := &v1.VirtualMachineInstance{
101 Spec: v1.VirtualMachineInstanceSpec{
102 Domain: v1.DomainSpec{},
103 },
104 }
105 pointer.BoolPtr(true)
106 vmi.Spec.Domain.Features = &v1.Features{
107 ACPI: v1.FeatureState{Enabled: pointer.BoolPtr(true)},
108 APIC: &v1.FeatureAPIC{Enabled: pointer.BoolPtr(false)},
109 Hyperv: &v1.FeatureHyperv{
110 Relaxed: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
111 VAPIC: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
112 Spinlocks: &v1.FeatureSpinlocks{Enabled: pointer.BoolPtr(true)},
113 VPIndex: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
114 Runtime: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
115 SyNIC: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
116 SyNICTimer: &v1.SyNICTimer{Enabled: pointer.BoolPtr(true), Direct: &v1.FeatureState{Enabled: pointer.BoolPtr(true)}},
117 Reset: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
118 VendorID: &v1.FeatureVendorID{Enabled: pointer.BoolPtr(true)},
119 Frequencies: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
120 Reenlightenment: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
121 TLBFlush: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
122 },
123 }
124 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
125
126 features := vmi.Spec.Domain.Features
127 hyperv := features.Hyperv
128
129 Expect(*features.ACPI.Enabled).To(BeTrue())
130 Expect(*features.APIC.Enabled).To(BeFalse())
131 Expect(*hyperv.Relaxed.Enabled).To(BeTrue())
132 Expect(*hyperv.VAPIC.Enabled).To(BeFalse())
133 Expect(*hyperv.Spinlocks.Enabled).To(BeTrue())
134 Expect(*hyperv.Spinlocks.Retries).To(Equal(uint32(4096)))
135 Expect(*hyperv.VPIndex.Enabled).To(BeFalse())
136 Expect(*hyperv.Runtime.Enabled).To(BeTrue())
137 Expect(*hyperv.SyNIC.Enabled).To(BeFalse())
138 Expect(*hyperv.SyNICTimer.Enabled).To(BeTrue())
139 Expect(*hyperv.SyNICTimer.Direct.Enabled).To(BeTrue())
140 Expect(*hyperv.Reset.Enabled).To(BeFalse())
141 Expect(*hyperv.VendorID.Enabled).To(BeTrue())
142 Expect(*hyperv.Frequencies.Enabled).To(BeFalse())
143 Expect(*hyperv.Reenlightenment.Enabled).To(BeFalse())
144 Expect(*hyperv.TLBFlush.Enabled).To(BeTrue())
145
146 vmi.Spec.Domain.Features = &v1.Features{
147 ACPI: v1.FeatureState{Enabled: pointer.BoolPtr(false)},
148 APIC: &v1.FeatureAPIC{Enabled: pointer.BoolPtr(true)},
149 Hyperv: &v1.FeatureHyperv{
150 Relaxed: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
151 VAPIC: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
152 Spinlocks: &v1.FeatureSpinlocks{Enabled: pointer.BoolPtr(false)},
153 VPIndex: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
154 Runtime: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
155 SyNIC: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
156 SyNICTimer: &v1.SyNICTimer{Enabled: pointer.BoolPtr(false)},
157 Reset: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
158 VendorID: &v1.FeatureVendorID{Enabled: pointer.BoolPtr(false)},
159 Frequencies: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
160 Reenlightenment: &v1.FeatureState{Enabled: pointer.BoolPtr(false)},
161 TLBFlush: &v1.FeatureState{Enabled: pointer.BoolPtr(true)},
162 },
163 }
164 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
165
166 features = vmi.Spec.Domain.Features
167 hyperv = features.Hyperv
168
169 Expect(*features.ACPI.Enabled).To(BeFalse())
170 Expect(*features.APIC.Enabled).To(BeTrue())
171 Expect(*hyperv.Relaxed.Enabled).To(BeFalse())
172 Expect(*hyperv.VAPIC.Enabled).To(BeTrue())
173 Expect(*hyperv.Spinlocks.Enabled).To(BeFalse())
174 Expect(hyperv.Spinlocks.Retries).To(BeNil())
175 Expect(*hyperv.VPIndex.Enabled).To(BeTrue())
176 Expect(*hyperv.Runtime.Enabled).To(BeFalse())
177 Expect(*hyperv.SyNIC.Enabled).To(BeTrue())
178 Expect(*hyperv.SyNICTimer.Enabled).To(BeFalse())
179 Expect(*hyperv.Reset.Enabled).To(BeTrue())
180 Expect(*hyperv.VendorID.Enabled).To(BeFalse())
181 Expect(*hyperv.Frequencies.Enabled).To(BeFalse())
182 Expect(*hyperv.Reenlightenment.Enabled).To(BeFalse())
183 Expect(*hyperv.TLBFlush.Enabled).To(BeTrue())
184 })
185
186 It("should set dis defaults", func() {
187 vmi := &v1.VirtualMachineInstance{
188 Spec: v1.VirtualMachineInstanceSpec{
189 Domain: v1.DomainSpec{
190 Devices: v1.Devices{
191 Disks: []v1.Disk{
192 {
193 Name: "cdrom_tray_unspecified",
194 DiskDevice: v1.DiskDevice{
195 CDRom: &v1.CDRomTarget{},
196 },
197 },
198 {
199 Name: "cdrom_tray_open",
200 DiskDevice: v1.DiskDevice{
201 CDRom: &v1.CDRomTarget{
202 Tray: v1.TrayStateOpen,
203 ReadOnly: pointer.BoolPtr(false),
204 },
205 },
206 },
207 {
208 Name: "should_default_to_disk",
209 },
210 },
211 },
212 },
213 },
214 }
215 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
216 disks := vmi.Spec.Domain.Devices.Disks
217
218 Expect(disks[0].CDRom.Tray).To(Equal(v1.TrayStateClosed), "Default tray state for CDROM should be closed")
219 Expect(*disks[0].CDRom.ReadOnly).To(BeTrue(), "Default ReadOnly state for CDROM should be true")
220 Expect(disks[0].DedicatedIOThread).To(BeNil(), "Default DedicatedIOThread state should be nil")
221 Expect(disks[1].CDRom.Tray).To(Equal(v1.TrayStateOpen), "Tray state was explicitly set to open")
222 Expect(*disks[1].CDRom.ReadOnly).To(BeFalse(), "ReadOnly state was explicitly set to true")
223 Expect(disks[1].DedicatedIOThread).To(BeNil(), "Default DedicatedIOThread state should be nil")
224 Expect(disks[2].Disk).ToNot(BeNil(), "Default type should be Disk")
225 Expect(disks[2].DedicatedIOThread).To(BeNil(), "Default DedicatedIOThread state should be nil")
226 })
227
228 It("should set the default watchdog and the default watchdog action", func() {
229 vmi := &v1.VirtualMachineInstance{
230 Spec: v1.VirtualMachineInstanceSpec{
231 Domain: v1.DomainSpec{
232 Devices: v1.Devices{
233 Watchdog: &v1.Watchdog{
234 WatchdogDevice: v1.WatchdogDevice{
235 I6300ESB: &v1.I6300ESBWatchdog{},
236 },
237 },
238 },
239 },
240 },
241 }
242 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
243 Expect(vmi.Spec.Domain.Devices.Watchdog.I6300ESB.Action).To(Equal(v1.WatchdogActionReset))
244 vmi.Spec.Domain.Devices.Watchdog.I6300ESB = nil
245 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
246 Expect(vmi.Spec.Domain.Devices.Watchdog.I6300ESB).ToNot(BeNil())
247 Expect(vmi.Spec.Domain.Devices.Watchdog.I6300ESB.Action).To(Equal(v1.WatchdogActionReset))
248 })
249
250 It("should set timer defaults", func() {
251 vmi := &v1.VirtualMachineInstance{
252 Spec: v1.VirtualMachineInstanceSpec{
253 Domain: v1.DomainSpec{
254 Clock: &v1.Clock{
255 Timer: &v1.Timer{
256 HPET: &v1.HPETTimer{},
257 KVM: &v1.KVMTimer{},
258 PIT: &v1.PITTimer{},
259 RTC: &v1.RTCTimer{},
260 Hyperv: &v1.HypervTimer{},
261 },
262 },
263 },
264 },
265 }
266 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
267 timer := vmi.Spec.Domain.Clock.Timer
268 Expect(*timer.HPET.Enabled).To(BeTrue())
269 Expect(*timer.KVM.Enabled).To(BeTrue())
270 Expect(*timer.PIT.Enabled).To(BeTrue())
271 Expect(*timer.RTC.Enabled).To(BeTrue())
272 Expect(*timer.Hyperv.Enabled).To(BeTrue())
273 })
274
275 It("should omit IOThreads by default", func() {
276 vmi := &v1.VirtualMachineInstance{}
277 v1.SetObjectDefaults_VirtualMachineInstance(vmi)
278 Expect(vmi.Spec.Domain.IOThreadsPolicy).To(BeNil(), "Default IOThreadsPolicy should be nil")
279 })
280 })
281
282 var _ = Describe("Function SetDefaults_NetworkInterface()", func() {
283
284 It("should append pod interface if interface is not defined", func() {
285 vmi := &v1.VirtualMachineInstance{}
286 v1.SetDefaults_NetworkInterface(vmi)
287 Expect(vmi.Spec.Domain.Devices.Interfaces).To(HaveLen(1))
288 Expect(vmi.Spec.Domain.Devices.Interfaces[0].Name).To(Equal("default"))
289 Expect(vmi.Spec.Networks[0].Name).To(Equal("default"))
290 Expect(vmi.Spec.Networks[0].Pod).ToNot(BeNil())
291 })
292
293 It("should not append pod interface if interface is defined", func() {
294 vmi := &v1.VirtualMachineInstance{}
295 net := v1.Network{
296 Name: "testnet",
297 }
298 iface := v1.Interface{Name: net.Name}
299 vmi.Spec.Networks = []v1.Network{net}
300 vmi.Spec.Domain.Devices.Interfaces = []v1.Interface{iface}
301
302 v1.SetDefaults_NetworkInterface(vmi)
303 Expect(vmi.Spec.Domain.Devices.Interfaces).To(HaveLen(1))
304 Expect(vmi.Spec.Domain.Devices.Interfaces[0].Name).To(Equal("testnet"))
305 Expect(vmi.Spec.Networks[0].Name).To(Equal("testnet"))
306 Expect(vmi.Spec.Networks[0].Pod).To(BeNil())
307 })
308
309 It("should not append pod interface if it's explicitly disabled", func() {
310 autoAttach := false
311 vmi := &v1.VirtualMachineInstance{}
312 vmi.Spec.Domain.Devices.AutoattachPodInterface = &autoAttach
313
314 v1.SetDefaults_NetworkInterface(vmi)
315 Expect(vmi.Spec.Domain.Devices.Interfaces).To(BeEmpty())
316 Expect(vmi.Spec.Networks).To(BeEmpty())
317 })
318
319 It("should append pod interface if auto attach is true", func() {
320 autoAttach := true
321 vmi := &v1.VirtualMachineInstance{}
322 vmi.Spec.Domain.Devices.AutoattachPodInterface = &autoAttach
323 v1.SetDefaults_NetworkInterface(vmi)
324 Expect(vmi.Spec.Domain.Devices.Interfaces).To(HaveLen(1))
325 Expect(vmi.Spec.Domain.Devices.Interfaces[0].Name).To(Equal("default"))
326 Expect(vmi.Spec.Networks[0].Name).To(Equal("default"))
327 Expect(vmi.Spec.Networks[0].Pod).ToNot(BeNil())
328 })
329
330 It("should default probes", func() {
331 vmi := &v1.VirtualMachineInstance{
332 Spec: v1.VirtualMachineInstanceSpec{
333 ReadinessProbe: &v1.Probe{},
334 LivenessProbe: &v1.Probe{},
335 },
336 }
337 v1.SetDefaults_VirtualMachineInstance(vmi)
338
339 validateProbe := func(probe *v1.Probe) {
340 Expect(probe.TimeoutSeconds).To(BeEquivalentTo(1))
341 Expect(probe.PeriodSeconds).To(BeEquivalentTo(10))
342 Expect(probe.SuccessThreshold).To(BeEquivalentTo(1))
343 Expect(probe.FailureThreshold).To(BeEquivalentTo(3))
344 }
345 validateProbe(vmi.Spec.ReadinessProbe)
346 validateProbe(vmi.Spec.LivenessProbe)
347 })
348 })
349
View as plain text