diff --git a/images/virtualization-artifact/pkg/builder/vm/option.go b/images/virtualization-artifact/pkg/builder/vm/option.go index bd1b8692cc..f250e32f0e 100644 --- a/images/virtualization-artifact/pkg/builder/vm/option.go +++ b/images/virtualization-artifact/pkg/builder/vm/option.go @@ -17,11 +17,13 @@ limitations under the License. package vm import ( + "k8s.io/apimachinery/pkg/api/resource" + "github.com/deckhouse/virtualization-controller/pkg/builder/meta" "github.com/deckhouse/virtualization/api/core/v1alpha2" ) -type Option func(vmop *v1alpha2.VirtualMachine) +type Option func(vm *v1alpha2.VirtualMachine) var ( WithName = meta.WithName[*v1alpha2.VirtualMachine] @@ -32,3 +34,18 @@ var ( WithAnnotation = meta.WithAnnotation[*v1alpha2.VirtualMachine] WithAnnotations = meta.WithAnnotations[*v1alpha2.VirtualMachine] ) + +func WithCPU(cores int, coreFraction *string) Option { + return func(vm *v1alpha2.VirtualMachine) { + vm.Spec.CPU.Cores = cores + if coreFraction != nil { + vm.Spec.CPU.CoreFraction = *coreFraction + } + } +} + +func WithMemory(size resource.Quantity) Option { + return func(vm *v1alpha2.VirtualMachine) { + vm.Spec.Memory.Size = size + } +} diff --git a/images/virtualization-artifact/pkg/common/kvvm/kvvm.go b/images/virtualization-artifact/pkg/common/kvvm/kvvm.go index c850e60492..d1dcac118c 100644 --- a/images/virtualization-artifact/pkg/common/kvvm/kvvm.go +++ b/images/virtualization-artifact/pkg/common/kvvm/kvvm.go @@ -17,8 +17,10 @@ limitations under the License. package kvvm import ( + "cmp" "context" "fmt" + "slices" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" @@ -63,29 +65,38 @@ func FindPodByKVVMI(ctx context.Context, cli client.Client, kvvmi *virtv1.Virtua } func GetVMPod(kvvmi *virtv1.VirtualMachineInstance, podList *corev1.PodList) *corev1.Pod { - if len(podList.Items) == 0 { + if kvvmi == nil { return nil } - if len(podList.Items) == 1 { - return &podList.Items[0] - } - // If migration is completed - return the target pod. - if kvvmi != nil && kvvmi.Status.MigrationState != nil && kvvmi.Status.MigrationState.Completed { - for _, pod := range podList.Items { - if pod.Name == kvvmi.Status.MigrationState.TargetPod { - return &pod - } + var pods []corev1.Pod + for _, pod := range podList.Items { + if pod.Spec.NodeName != kvvmi.Status.NodeName { + continue } + if _, exists := kvvmi.Status.ActivePods[pod.GetUID()]; !exists { + continue + } + pods = append(pods, pod) } - // Return the first Running Pod or just a first Pod. - for _, pod := range podList.Items { + switch len(pods) { + case 0: + return nil + case 1: + return &pods[0] + } + + slices.SortFunc(pods, func(a, b corev1.Pod) int { + return cmp.Compare(a.GetCreationTimestamp().UnixNano(), b.GetCreationTimestamp().UnixNano()) + }) + + for _, pod := range pods { if pod.Status.Phase == corev1.PodRunning { return &pod } } - return &podList.Items[0] + return &pods[0] } // DeletePodByKVVMI deletes pod by kvvmi. diff --git a/images/virtualization-artifact/pkg/controller/powerstate/operations_test.go b/images/virtualization-artifact/pkg/controller/powerstate/operations_test.go index 4a400fdc5b..89675ba3f8 100644 --- a/images/virtualization-artifact/pkg/controller/powerstate/operations_test.go +++ b/images/virtualization-artifact/pkg/controller/powerstate/operations_test.go @@ -35,7 +35,9 @@ func TestRestartVM(t *testing.T) { const ( vmName = "test-vm" vmNamespace = "test-namespace" - uid types.UID = "test-uid" + nodeName = "worker-01" + kvvmiUID types.UID = "test-kvvmi-uid" + podUID types.UID = "test-pod-uid" ) key := types.NamespacedName{ Name: vmName, @@ -57,12 +59,18 @@ func TestRestartVM(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: vmName, Namespace: vmNamespace, - UID: uid, + UID: kvvmiUID, }, TypeMeta: metav1.TypeMeta{ Kind: "VirtualMachineInstance", APIVersion: virtv1.SchemeGroupVersion.String(), }, + Status: virtv1.VirtualMachineInstanceStatus{ + NodeName: nodeName, + ActivePods: map[types.UID]string{ + podUID: vmName, + }, + }, } pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -70,8 +78,12 @@ func TestRestartVM(t *testing.T) { Namespace: vmNamespace, Labels: map[string]string{ virtv1.AppLabel: "virt-launcher", - virtv1.CreatedByLabel: string(uid), + virtv1.CreatedByLabel: string(kvvmiUID), }, + UID: podUID, + }, + Spec: corev1.PodSpec{ + NodeName: nodeName, }, TypeMeta: metav1.TypeMeta{ Kind: "Pod", @@ -118,7 +130,7 @@ func TestRestartVM(t *testing.T) { require.Len(t, newKVVM.Status.StateChangeRequests, 2) require.Equal(t, virtv1.StopRequest, newKVVM.Status.StateChangeRequests[0].Action) require.NotNil(t, newKVVM.Status.StateChangeRequests[0].UID) - require.Equal(t, uid, *newKVVM.Status.StateChangeRequests[0].UID) + require.Equal(t, kvvmiUID, *newKVVM.Status.StateChangeRequests[0].UID) require.Equal(t, virtv1.StartRequest, newKVVM.Status.StateChangeRequests[1].Action) pod := &corev1.Pod{} diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/statistic_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/statistic_test.go index 3f0aeca30a..05a0340518 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/statistic_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/statistic_test.go @@ -18,195 +18,200 @@ package internal import ( "context" - "fmt" - "testing" - "github.com/stretchr/testify/require" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - apiruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" + vmbuilder "github.com/deckhouse/virtualization-controller/pkg/builder/vm" + "github.com/deckhouse/virtualization-controller/pkg/common/testutil" "github.com/deckhouse/virtualization-controller/pkg/controller/reconciler" "github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state" virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" ) -func TestStatisticHandler(t *testing.T) { - scheme := apiruntime.NewScheme() - for _, f := range []func(*apiruntime.Scheme) error{ - virtv2.AddToScheme, - virtv1.AddToScheme, - corev1.AddToScheme, - } { - err := f(scheme) - if err != nil { - t.Fatalf("failed to add scheme: %v", err) +var _ = Describe("TestStatisticHandler", func() { + const ( + vmName = "vm" + vmNamespace = "default" + podName = "test-pod" + nodeName = "test-node" + podUID types.UID = "test-pod-uid" + ) + + newVM := func(cores int, coreFraction *string, memorySize string) *virtv2.VirtualMachine { + vm := vmbuilder.New( + vmbuilder.WithName(vmName), + vmbuilder.WithNamespace(vmNamespace), + vmbuilder.WithCPU(cores, coreFraction), + vmbuilder.WithMemory(resource.MustParse(memorySize)), + ) + vm.Status = virtv2.VirtualMachineStatus{ + Phase: virtv2.MachineRunning, } + + return vm } - namespacedName := types.NamespacedName{Name: "test-vm", Namespace: "test-namespace"} - - for _, test := range []struct { - name string - getObjects func() []client.Object - mutateChanged func(vm *virtv2.VirtualMachine) - expect func(vm *virtv2.VirtualMachine) error - }{ - { - name: "test1: check generated .status.resources", - getObjects: func() []client.Object { - return []client.Object{ - createPod(namespacedName), - createVM(namespacedName, virtv2.MachineRunning, nil, virtv1.VirtualMachineInstanceGuestOSInfo{}), - createKVVMI(namespacedName, virtv1.Running, virtv1.VirtualMachineInstanceGuestOSInfo{Name: "test"}), - } - }, - mutateChanged: func(vm *virtv2.VirtualMachine) {}, - expect: func(vm *virtv2.VirtualMachine) error { - require.NotNil(t, vm) - res := vm.Status.Resources - require.Equal(t, 1, res.CPU.Cores) - require.Equal(t, "50%", res.CPU.CoreFraction) - require.Equal(t, int64(500), res.CPU.RequestedCores.MilliValue()) - require.Equal(t, int64(0), res.CPU.RuntimeOverhead.MilliValue()) - - require.NotNil(t, res.CPU.Topology) - require.Equal(t, 1, res.CPU.Topology.CoresPerSocket) - require.Equal(t, 1, res.CPU.Topology.Sockets) - - require.Equal(t, int64(536870912), res.Memory.Size.Value()) - require.Equal(t, int64(254803968), res.Memory.RuntimeOverhead.Value()) - - return nil + newKVVMI := func(requestCPU, limitCPU, requestMemory, limitMemory string) *virtv1.VirtualMachineInstance { + kvvmi := newEmptyKVVMI(vmName, vmNamespace) + kvvmi.Spec = virtv1.VirtualMachineInstanceSpec{ + Domain: virtv1.DomainSpec{ + Resources: virtv1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse(requestCPU), + corev1.ResourceMemory: resource.MustParse(requestMemory), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse(limitCPU), + corev1.ResourceMemory: resource.MustParse(limitMemory), + }, + }, }, - }, - } { - t.Log("Start test", test.name) - fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(test.getObjects()...).Build() - vm := reconciler.NewResource(namespacedName, fakeClient, factory, statusGetter) - if err := vm.Fetch(context.Background()); err != nil { - t.Fatalf("failed to fetch resource: %v", err) - } - s := state.New(fakeClient, vm) - test.mutateChanged(s.VirtualMachine().Changed()) - handler := NewStatisticHandler(fakeClient) - _, err := handler.Handle(context.Background(), s) - if err != nil { - t.Fatalf("failed to sync stats: %v", err) } - if err = test.expect(s.VirtualMachine().Changed()); err != nil { - t.Fatalf("test %q failed: %v", test.name, err) + kvvmi.Status = virtv1.VirtualMachineInstanceStatus{ + ActivePods: map[types.UID]string{podUID: podName}, + NodeName: nodeName, + Phase: virtv1.Running, } + return kvvmi } -} -func createPod(vmKey types.NamespacedName) *corev1.Pod { - return &corev1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("virt-launcher-%s", vmKey.Name), - Namespace: vmKey.Namespace, - Labels: map[string]string{ - virtv1.VirtualMachineNameLabel: vmKey.Name, - }, - }, - Spec: corev1.PodSpec{ + newPod := func(requestCPU, limitCPU, requestMemory, limitMemory string) *corev1.Pod { + pod := newEmptyPOD(podName, vmNamespace, vmName) + pod.UID = podUID + pod.Spec = corev1.PodSpec{ + NodeName: nodeName, Containers: []corev1.Container{ { Name: "compute", Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("755Mi"), + corev1.ResourceCPU: resource.MustParse(requestCPU), + corev1.ResourceMemory: resource.MustParse(requestMemory), }, Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("755Mi"), + corev1.ResourceCPU: resource.MustParse(limitCPU), + corev1.ResourceMemory: resource.MustParse(limitMemory), }, }, }, }, - }, + } + return pod } -} - -func createVM(key types.NamespacedName, - phase virtv2.MachinePhase, - stats *virtv2.VirtualMachineStats, - guestOSInfo virtv1.VirtualMachineInstanceGuestOSInfo, -) *virtv2.VirtualMachine { - return &virtv2.VirtualMachine{ - TypeMeta: metav1.TypeMeta{ - Kind: virtv2.VirtualMachineKind, - APIVersion: virtv2.GroupVersionResource(virtv2.VirtualMachineKind).GroupVersion().String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, - }, - Spec: virtv2.VirtualMachineSpec{ - CPU: virtv2.CPUSpec{ - Cores: 1, - CoreFraction: "50%", - }, - Memory: virtv2.MemorySpec{ - Size: resource.MustParse("512Mi"), - }, - }, - Status: virtv2.VirtualMachineStatus{ - Phase: phase, - Stats: stats, - GuestOSInfo: guestOSInfo, - }, + + var ( + ctx = testutil.ContextBackgroundWithNoOpLogger() + fakeClient client.Client + vmResource *reconciler.Resource[*virtv2.VirtualMachine, virtv2.VirtualMachineStatus] + vmState state.VirtualMachineState + ) + + reconcile := func() { + h := NewStatisticHandler(fakeClient) + _, err := h.Handle(context.Background(), vmState) + Expect(err).NotTo(HaveOccurred()) + err = vmResource.Update(ctx) + Expect(err).NotTo(HaveOccurred()) } -} - -func createKVVMI(key types.NamespacedName, - phase virtv1.VirtualMachineInstancePhase, - guestOSInfo virtv1.VirtualMachineInstanceGuestOSInfo, -) *virtv1.VirtualMachineInstance { - return &virtv1.VirtualMachineInstance{ - TypeMeta: metav1.TypeMeta{ - Kind: virtv1.VirtualMachineGroupVersionKind.Kind, - APIVersion: virtv1.VirtualMachineGroupVersionKind.GroupVersion().String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, - }, - Spec: virtv1.VirtualMachineInstanceSpec{ - Domain: virtv1.DomainSpec{ - Resources: virtv1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("500m"), - corev1.ResourceMemory: resource.MustParse("512Mi"), - }, - Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse("512Mi"), - }, - }, - }, - }, - Status: virtv1.VirtualMachineInstanceStatus{ - Phase: phase, - GuestOSInfo: guestOSInfo, - }, + + AfterEach(func() { + fakeClient = nil + vmResource = nil + vmState = nil + }) + + type expectedValues struct { + CPUCores int + CPUCoreFraction string + CPURequestedCores int64 + CPURuntimeOverhead int64 + + TopologyCoresPerSocket int + TopologySockets int + + MemorySize int64 + MemoryRuntimeOverhead int64 } -} -func factory() *virtv2.VirtualMachine { - return &virtv2.VirtualMachine{} -} + DescribeTable("Check Generated .status.resources", + func(vm *virtv2.VirtualMachine, kvvmi *virtv1.VirtualMachineInstance, pod *corev1.Pod, expect expectedValues) { + fakeClient, vmResource, vmState = setupEnvironment(vm, kvvmi, pod) + reconcile() + + newVM := &virtv2.VirtualMachine{} + err := fakeClient.Get(ctx, client.ObjectKeyFromObject(vm), newVM) + Expect(err).NotTo(HaveOccurred()) + + res := newVM.Status.Resources + Expect(res.CPU.Cores).To(Equal(expect.CPUCores)) + Expect(res.CPU.CoreFraction).To(Equal(expect.CPUCoreFraction)) + Expect(res.CPU.RequestedCores.MilliValue()).To(Equal(expect.CPURequestedCores)) + Expect(res.CPU.RuntimeOverhead.MilliValue()).To(Equal(expect.CPURuntimeOverhead)) -func statusGetter(obj *virtv2.VirtualMachine) virtv2.VirtualMachineStatus { - return obj.Status -} + Expect(res.CPU.Topology).ShouldNot(BeNil()) + Expect(res.CPU.Topology.CoresPerSocket).To(Equal(expect.TopologyCoresPerSocket)) + Expect(res.CPU.Topology.Sockets).To(Equal(expect.TopologySockets)) + + Expect(res.Memory.Size.Value()).To(Equal(expect.MemorySize)) + Expect(res.Memory.RuntimeOverhead.Value()).To(Equal(expect.MemoryRuntimeOverhead)) + }, + Entry("Case 1", + newVM(1, ptr.To("50%"), "512Mi"), + newKVVMI("500m", "1", "512Mi", "512Mi"), + newPod("500m", "1", "755Mi", "755Mi"), + expectedValues{ + CPUCores: 1, + CPUCoreFraction: "50%", + CPURequestedCores: 500, + CPURuntimeOverhead: 0, + + TopologyCoresPerSocket: 1, + TopologySockets: 1, + + MemorySize: 536870912, + MemoryRuntimeOverhead: 254803968, + }, + ), + Entry("Case 2", + newVM(4, ptr.To("25%"), "8Gi"), + newKVVMI("1", "4", "8Gi", "8Gi"), + newPod("1", "4", "8Gi", "8Gi"), + expectedValues{ + CPUCores: 4, + CPUCoreFraction: "25%", + CPURequestedCores: 1000, + CPURuntimeOverhead: 0, + + TopologyCoresPerSocket: 4, + TopologySockets: 1, + + MemorySize: 8589934592, + MemoryRuntimeOverhead: 0, + }, + ), + Entry("Case 3", + newVM(2, ptr.To("100%"), "2Gi"), + newKVVMI("2", "2", "2Gi", "2Gi"), + newPod("2", "2", "2Gi", "2Gi"), + expectedValues{ + CPUCores: 2, + CPUCoreFraction: "100%", + CPURequestedCores: 2000, + CPURuntimeOverhead: 0, + + TopologyCoresPerSocket: 2, + TopologySockets: 1, + + MemorySize: 2147483648, + MemoryRuntimeOverhead: 0, + }, + ), + ) +}) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/suite_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/suite_test.go index e8e6594015..c71534d2f4 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/suite_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/suite_test.go @@ -22,8 +22,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -47,11 +47,7 @@ func setupEnvironment(vm *virtv2.VirtualMachine, objs ...client.Object) (client. fakeClient, err := testutil.NewFakeClientWithObjects(allObjects...) Expect(err).NotTo(HaveOccurred()) - key := types.NamespacedName{ - Name: vm.GetName(), - Namespace: vm.GetNamespace(), - } - resource := reconciler.NewResource(key, fakeClient, + resource := reconciler.NewResource(client.ObjectKeyFromObject(vm), fakeClient, func() *virtv2.VirtualMachine { return &virtv2.VirtualMachine{} }, @@ -78,3 +74,19 @@ func newEmptyKVVMI(name, namespace string) *virtv1.VirtualMachineInstance { }, } } + +func newEmptyPOD(name, namespace, vmName string) *corev1.Pod { + return &corev1.Pod{ + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{ + virtv1.VirtualMachineNameLabel: vmName, + }, + }, + } +} diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state_test.go index 5f7a238ca4..5d5dcc5a28 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state_test.go @@ -18,31 +18,26 @@ package internal import ( "context" - "log/slog" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" + + "github.com/deckhouse/virtualization-controller/pkg/common/testutil" "github.com/deckhouse/virtualization-controller/pkg/common/annotations" "github.com/deckhouse/virtualization-controller/pkg/controller/powerstate" - "github.com/deckhouse/virtualization-controller/pkg/controller/reconciler" "github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state" "github.com/deckhouse/virtualization-controller/pkg/eventrecord" - "github.com/deckhouse/virtualization-controller/pkg/logger" virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" ) var _ = Describe("Test power actions with VMs", func() { var ( - scheme *runtime.Scheme ctx context.Context handler *SyncPowerStateHandler recorderMock *eventrecord.EventRecorderLoggerMock @@ -64,35 +59,15 @@ var _ = Describe("Test power actions with VMs", func() { recorderMock = nil vmState = nil handler = nil - scheme = nil }) setupTestEnvironment := func() { - fakeClient = fake.NewClientBuilder(). - WithScheme(scheme). - WithObjects(vm, kvvm, kvvmi, vmPod). - WithStatusSubresource(vm, kvvm, kvvmi). - Build() - - vmResource := reconciler.NewResource( - types.NamespacedName{Namespace: namespacedVirtualMachine.Namespace, Name: namespacedVirtualMachine.Name}, - fakeClient, - vmFactoryByVm(vm), - vmStatusGetter, - ) - - err := vmResource.Fetch(ctx) - if err != nil { - return - } - - vmState = state.New(fakeClient, vmResource) + fakeClient, _, vmState = setupEnvironment(vm, kvvm, kvvmi, vmPod) handler = NewSyncPowerStateHandler(fakeClient, recorderMock) } BeforeEach(func() { - scheme = setupScheme() - ctx = logger.ToContext(context.TODO(), slog.Default()) + ctx = testutil.ContextBackgroundWithNoOpLogger() namespacedVirtualMachine = types.NamespacedName{ Namespace: "vm", Name: "ns", @@ -150,7 +125,6 @@ var _ = Describe("Test power actions with VMs", func() { var _ = Describe("Test action getters for different run policy", func() { var ( - scheme *runtime.Scheme ctx context.Context handler *SyncPowerStateHandler recorderMock *eventrecord.EventRecorderLoggerMock @@ -164,19 +138,14 @@ var _ = Describe("Test action getters for different run policy", func() { ) BeforeEach(func() { - scheme = setupScheme() - ctx = logger.ToContext(context.TODO(), slog.Default()) + ctx = testutil.ContextBackgroundWithNoOpLogger() namespacedVirtualMachine = types.NamespacedName{ Namespace: "vm", Name: "ns", } vm, kvvm, kvvmi, vmPod = createObjectsForPowerstateTest(namespacedVirtualMachine) - fakeClient = fake.NewClientBuilder(). - WithScheme(scheme). - WithObjects(vm, kvvm, kvvmi, vmPod). - WithStatusSubresource(vm, kvvm, kvvmi). - Build() + fakeClient, _, vmState = setupEnvironment(vm, kvvm, kvvmi, vmPod) recorderMock = &eventrecord.EventRecorderLoggerMock{ EventfFunc: func(client.Object, string, string, string, ...interface{}) {}, @@ -185,19 +154,6 @@ var _ = Describe("Test action getters for different run policy", func() { }, } - vmResource := reconciler.NewResource( - types.NamespacedName{Namespace: namespacedVirtualMachine.Namespace, Name: namespacedVirtualMachine.Name}, - fakeClient, - vmFactoryByVm(vm), - vmStatusGetter, - ) - - err := vmResource.Fetch(ctx) - if err != nil { - return - } - - vmState = state.New(fakeClient, vmResource) handler = NewSyncPowerStateHandler(fakeClient, recorderMock) }) @@ -210,7 +166,6 @@ var _ = Describe("Test action getters for different run policy", func() { recorderMock = nil vmState = nil handler = nil - scheme = nil }) Context("handleManualPolicy", func() { @@ -406,15 +361,12 @@ var _ = Describe("Test action getters for different run policy", func() { }) }) -func setupScheme() *runtime.Scheme { - scheme := runtime.NewScheme() - Expect(clientgoscheme.AddToScheme(scheme)).To(Succeed()) - Expect(virtv2.AddToScheme(scheme)).To(Succeed()) - Expect(virtv1.AddToScheme(scheme)).To(Succeed()) - return scheme -} - func createObjectsForPowerstateTest(namespacedVirtualMachine types.NamespacedName) (*virtv2.VirtualMachine, *virtv1.VirtualMachine, *virtv1.VirtualMachineInstance, *corev1.Pod) { + const ( + podName = "test-pod" + nodeName = "test-node" + podUID types.UID = "test-pod-uid" + ) vm := &virtv2.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: namespacedVirtualMachine.Name, @@ -435,13 +387,22 @@ func createObjectsForPowerstateTest(namespacedVirtualMachine types.NamespacedNam Name: namespacedVirtualMachine.Name, Namespace: namespacedVirtualMachine.Namespace, }, - Status: virtv1.VirtualMachineInstanceStatus{}, + Status: virtv1.VirtualMachineInstanceStatus{ + ActivePods: map[types.UID]string{ + podUID: podName, + }, + NodeName: nodeName, + }, } vmPod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", + Name: podName, Namespace: namespacedVirtualMachine.Namespace, Labels: map[string]string{virtv1.VirtualMachineNameLabel: namespacedVirtualMachine.Name}, + UID: podUID, + }, + Spec: corev1.PodSpec{ + NodeName: nodeName, }, } return vm, kvvm, kvvmi, vmPod