Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 79 additions & 30 deletions test/e2e/vm/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import (
"context"
"fmt"
"strings"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
crclient "sigs.k8s.io/controller-runtime/pkg/client"

Expand All @@ -38,87 +40,134 @@ import (
)

const (
initialCPUCores = 1
initialMemorySize = "256Mi"
changedCPUCores = 2
changedMemorySize = "512Mi"
initialCPUCores = 1
initialMemorySize = "256Mi"
initialCoreFraction = "5%"
changedCPUCores = 2
changedMemorySize = "512Mi"
changedCoreFraction = "10%"
)

var _ = Describe("VirtualMachineConfiguration", func() {
DescribeTable("the configuration should be applied", func(restartApprovalMode v1alpha2.RestartApprovalMode) {
f := framework.NewFramework(fmt.Sprintf("vm-configuration-%s", strings.ToLower(string(restartApprovalMode))))
t := NewConfigurationTest(f)

DeferCleanup(f.After)
f.Before()

By("Environment preparation")
vm, vd := generateConfigurationResources(f.Namespace().Name, restartApprovalMode)
err := f.CreateWithDeferredDeletion(context.Background(), vm, vd)
t.GenerateConfigurationResources(restartApprovalMode)
err := f.CreateWithDeferredDeletion(context.Background(), t.VM, t.VDRoot, t.VDBlank)
Expect(err).NotTo(HaveOccurred())

By("Waiting for VM agent to be ready")
util.UntilVMAgentReady(crclient.ObjectKeyFromObject(vm), framework.LongTimeout)
util.UntilVMAgentReady(crclient.ObjectKeyFromObject(t.VM), framework.LongTimeout)

By("Checking initial configuration")
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(vm), vm)
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(t.VM), t.VM)
Expect(err).NotTo(HaveOccurred())
Expect(vm.Status.Resources.CPU.Cores).To(Equal(initialCPUCores))
Expect(vm.Status.Resources.Memory.Size).To(Equal(resource.MustParse(initialMemorySize)))
Expect(t.VM.Status.Resources.CPU.Cores).To(Equal(initialCPUCores))
Expect(t.VM.Status.Resources.Memory.Size).To(Equal(resource.MustParse(initialMemorySize)))
Expect(t.VM.Status.Resources.CPU.CoreFraction).To(Equal(initialCoreFraction))
Expect(t.IsVDInVMStatus(t.VDBlank, t.VM)).To(BeFalse())

By("Applying changes")
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(vm), vm)
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(t.VM), t.VM)
Expect(err).NotTo(HaveOccurred())
runningCondition, _ := conditions.GetCondition(vmcondition.TypeRunning, vm.Status.Conditions)
runningCondition, _ := conditions.GetCondition(vmcondition.TypeRunning, t.VM.Status.Conditions)
previousRunningTime := runningCondition.LastTransitionTime.Time

vm.Spec.CPU.Cores = changedCPUCores
vm.Spec.Memory.Size = resource.MustParse(changedMemorySize)
err = f.Clients.GenericClient().Update(context.Background(), vm)
t.VM.Spec.CPU.Cores = changedCPUCores
t.VM.Spec.Memory.Size = resource.MustParse(changedMemorySize)
t.VM.Spec.CPU.CoreFraction = changedCoreFraction
t.VM.Spec.BlockDeviceRefs = append(t.VM.Spec.BlockDeviceRefs, v1alpha2.BlockDeviceSpecRef{
Kind: v1alpha2.DiskDevice,
Name: t.VDBlank.Name,
})
err = f.Clients.GenericClient().Update(context.Background(), t.VM)
Expect(err).NotTo(HaveOccurred())

if restartApprovalMode == v1alpha2.Manual {
util.RebootVirtualMachineBySSH(f, vm)
time.Sleep(time.Second) // Avoid race condition with need restart condition calculation
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(t.VM), t.VM)
Expect(err).NotTo(HaveOccurred())
needRestart, _ := conditions.GetCondition(vmcondition.TypeAwaitingRestartToApplyConfiguration, t.VM.Status.Conditions)
Expect(needRestart.Status).To(Equal(metav1.ConditionTrue))
Expect(t.VM.Status.RestartAwaitingChanges).NotTo(BeNil())

util.RebootVirtualMachineBySSH(f, t.VM)
}

By("Waiting for VM to be rebooted")
util.UntilVirtualMachineRebooted(crclient.ObjectKeyFromObject(vm), previousRunningTime, framework.LongTimeout)
util.UntilVMAgentReady(crclient.ObjectKeyFromObject(vm), framework.ShortTimeout)
util.UntilVirtualMachineRebooted(crclient.ObjectKeyFromObject(t.VM), previousRunningTime, framework.LongTimeout)
util.UntilVMAgentReady(crclient.ObjectKeyFromObject(t.VM), framework.ShortTimeout)

By("Checking changed configuration")
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(vm), vm)
err = f.Clients.GenericClient().Get(context.Background(), crclient.ObjectKeyFromObject(t.VM), t.VM)
Expect(err).NotTo(HaveOccurred())
Expect(vm.Status.Resources.CPU.Cores).To(Equal(changedCPUCores))
Expect(vm.Status.Resources.Memory.Size).To(Equal(resource.MustParse(changedMemorySize)))
Expect(t.VM.Status.Resources.CPU.Cores).To(Equal(changedCPUCores))
Expect(t.VM.Status.Resources.Memory.Size).To(Equal(resource.MustParse(changedMemorySize)))
Expect(t.VM.Status.Resources.CPU.CoreFraction).To(Equal(changedCoreFraction))
Expect(t.IsVDInVMStatus(t.VDBlank, t.VM)).To(BeTrue())
},
Entry("when changes are applied manually", v1alpha2.Manual),
Entry("when changes are applied automatically", v1alpha2.Automatic),
)
})

func generateConfigurationResources(namespace string, restartApprovalMode v1alpha2.RestartApprovalMode) (vm *v1alpha2.VirtualMachine, vd *v1alpha2.VirtualDisk) {
vd = vdbuilder.New(
vdbuilder.WithName("vd"),
vdbuilder.WithNamespace(namespace),
type configurationTest struct {
Framework *framework.Framework

VM *v1alpha2.VirtualMachine
VDRoot *v1alpha2.VirtualDisk
VDBlank *v1alpha2.VirtualDisk
}

func NewConfigurationTest(f *framework.Framework) *configurationTest {
return &configurationTest{
Framework: f,
}
}

func (c *configurationTest) GenerateConfigurationResources(restartApprovalMode v1alpha2.RestartApprovalMode) {
c.VDRoot = vdbuilder.New(
vdbuilder.WithName("vd-root"),
vdbuilder.WithNamespace(c.Framework.Namespace().Name),
vdbuilder.WithDataSourceHTTP(&v1alpha2.DataSourceHTTP{
URL: object.ImageURLUbuntu,
}),
)

vm = vmbuilder.New(
c.VDBlank = vdbuilder.New(
vdbuilder.WithName("vd-blank"),
vdbuilder.WithNamespace(c.Framework.Namespace().Name),
vdbuilder.WithSize(ptr.To(resource.MustParse("100Mi"))),
)

c.VM = vmbuilder.New(
vmbuilder.WithName("vm"),
vmbuilder.WithNamespace(namespace),
vmbuilder.WithCPU(1, ptr.To("5%")),
vmbuilder.WithNamespace(c.Framework.Namespace().Name),
vmbuilder.WithCPU(1, ptr.To(initialCoreFraction)),
vmbuilder.WithMemory(resource.MustParse(initialMemorySize)),
vmbuilder.WithLiveMigrationPolicy(v1alpha2.AlwaysSafeMigrationPolicy),
vmbuilder.WithVirtualMachineClass(object.DefaultVMClass),
vmbuilder.WithProvisioningUserData(object.DefaultCloudInit),
vmbuilder.WithBlockDeviceRefs(
v1alpha2.BlockDeviceSpecRef{
Kind: v1alpha2.DiskDevice,
Name: vd.Name,
Name: c.VDRoot.Name,
},
),
vmbuilder.WithRestartApprovalMode(restartApprovalMode),
)
}

return
func (c *configurationTest) IsVDInVMStatus(vd *v1alpha2.VirtualDisk, vm *v1alpha2.VirtualMachine) bool {
for _, bda := range vm.Status.BlockDeviceRefs {
if bda.Kind == v1alpha2.DiskDevice && bda.Name == vd.Name {
return true
}
}
return false
}
Loading