KubeOS/0011-KubeOS-fix-operator-bug-of-missing-deep-copy.patch
Yuhang Wei 1d36b74685 KubeOS:sync code from source master branch
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
2024-02-26 09:54:27 +08:00

666 lines
23 KiB
Diff

From a87666e17d729feb67f987fa7038ef83b3fa2e1b Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Mon, 14 Aug 2023 16:46:06 +0800
Subject: [PATCH 11/17] KubeOS: fix operator bug of missing deep copy
Fixed bug where operator didn't perform deep copy
add operator ut, testing in multiple nodes env
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/operator/controllers/os_controller.go | 44 +-
.../controllers/os_controller_test.go | 378 ++++++++++++++----
2 files changed, 330 insertions(+), 92 deletions(-)
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
index 620739b..d36f15d 100644
--- a/cmd/operator/controllers/os_controller.go
+++ b/cmd/operator/controllers/os_controller.go
@@ -15,6 +15,8 @@ package controllers
import (
"context"
+ "encoding/json"
+ "fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
@@ -188,7 +190,9 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
}
continue
}
- updateNodeAndOSins(ctx, r, os, &node, &osInstance)
+ if err := updateNodeAndOSins(ctx, r, os, &node, &osInstance); err != nil {
+ continue
+ }
count++
}
}
@@ -196,12 +200,16 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
}
func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
- node *corev1.Node, osInstance *upgradev1.OSInstance) {
+ node *corev1.Node, osInstance *upgradev1.OSInstance) error {
if osInstance.Spec.UpgradeConfigs.Version != os.Spec.UpgradeConfigs.Version {
- osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
+ if err := deepCopySpecConfigs(os, osInstance, values.UpgradeConfigName); err != nil {
+ return err
+ }
}
if osInstance.Spec.SysConfigs.Version != os.Spec.SysConfigs.Version {
- osInstance.Spec.SysConfigs = os.Spec.SysConfigs
+ if err := deepCopySpecConfigs(os, osInstance, values.SysConfigName); err != nil {
+ return err
+ }
// exchange "grub.cmdline.current" and "grub.cmdline.next"
for i, config := range osInstance.Spec.SysConfigs.Configs {
if config.Model == "grub.cmdline.current" {
@@ -215,11 +223,14 @@ func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgr
osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
if err := r.Update(ctx, osInstance); err != nil {
log.Error(err, "unable to update", "osInstance", osInstance.Name)
+ return err
}
node.Labels[values.LabelUpgrading] = ""
if err := r.Update(ctx, node); err != nil {
log.Error(err, "unable to label", "node", node.Name)
+ return err
}
+ return nil
}
func assignConfig(ctx context.Context, r common.ReadStatusWriter, sysConfigs upgradev1.SysConfigs,
@@ -307,3 +318,28 @@ func min(a, b int) int {
}
return b
}
+
+func deepCopySpecConfigs(os *upgradev1.OS, osinstance *upgradev1.OSInstance, configType string) error {
+ switch configType {
+ case values.UpgradeConfigName:
+ data, err := json.Marshal(os.Spec.UpgradeConfigs)
+ if err != nil {
+ return err
+ }
+ if err = json.Unmarshal(data, &osinstance.Spec.UpgradeConfigs); err != nil {
+ return err
+ }
+ case values.SysConfigName:
+ data, err := json.Marshal(os.Spec.SysConfigs)
+ if err != nil {
+ return err
+ }
+ if err = json.Unmarshal(data, &osinstance.Spec.SysConfigs); err != nil {
+ return err
+ }
+ default:
+ log.Error(nil, "configType "+configType+" cannot be recognized")
+ return fmt.Errorf("configType %s cannot be recognized", configType)
+ }
+ return nil
+}
diff --git a/cmd/operator/controllers/os_controller_test.go b/cmd/operator/controllers/os_controller_test.go
index 98de6d0..e59ce7e 100644
--- a/cmd/operator/controllers/os_controller_test.go
+++ b/cmd/operator/controllers/os_controller_test.go
@@ -17,19 +17,12 @@ import (
"testing"
"time"
- "github.com/agiledragon/gomonkey/v2"
"github.com/google/uuid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
- "k8s.io/client-go/kubernetes/scheme"
- "k8s.io/client-go/util/workqueue"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/event"
upgradev1 "openeuler.org/KubeOS/api/v1alpha1"
"openeuler.org/KubeOS/pkg/values"
@@ -37,8 +30,7 @@ import (
var _ = Describe("OsController", func() {
const (
- OSName = "test-os"
-
+ OSName = "test-os"
timeout = time.Second * 20
interval = time.Millisecond * 500
)
@@ -72,26 +64,33 @@ var _ = Describe("OsController", func() {
})
AfterEach(func() {
- desiredTestNamespace := &v1.Namespace{
- TypeMeta: metav1.TypeMeta{
- APIVersion: "v1",
- Kind: "Namespace",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: testNamespace,
- },
+ // delete all nodes
+ nodeList := &v1.NodeList{}
+ err := k8sClient.List(context.Background(), nodeList)
+ Expect(err).ToNot(HaveOccurred())
+ for _, node := range nodeList.Items {
+ k8sClient.Delete(context.Background(), &node)
}
- // Add any teardown steps that needs to be executed after each test
- err := k8sClient.Delete(context.Background(), desiredTestNamespace,
- client.PropagationPolicy(metav1.DeletePropagationForeground))
+ nodeList = &v1.NodeList{}
+ Eventually(func() bool {
+ err = k8sClient.List(context.Background(), nodeList)
+ if err != nil || len(nodeList.Items) != 0 {
+ return false
+ }
+ return true
+ }, timeout, interval).Should(BeTrue())
+ // delete all OS CRs
+ osList := &upgradev1.OSList{}
+ err = k8sClient.List(context.Background(), osList)
Expect(err).ToNot(HaveOccurred())
-
- existingNamespace := &v1.Namespace{}
+ for _, os := range osList.Items {
+ k8sClient.Delete(context.Background(), &os)
+ }
+ osList = &upgradev1.OSList{}
Eventually(func() bool {
- err := k8sClient.Get(context.Background(), types.NamespacedName{Name: testNamespace},
- existingNamespace)
- if err != nil && errors.IsNotFound(err) {
+ err = k8sClient.List(context.Background(), osList)
+ if err != nil || len(osList.Items) != 0 {
return false
}
return true
@@ -102,7 +101,7 @@ var _ = Describe("OsController", func() {
It("Should label the osinstance's nodestatus to upgrading", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -131,7 +130,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
- // create OSInstance
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -163,6 +162,67 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v2",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
// create OS CR
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
@@ -206,13 +266,20 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+
+ createdOSIns2 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
})
})
Context("When we want to configure node", func() {
It("Should update OSInstance spec and update NodeStatus to config", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -228,7 +295,7 @@ var _ = Describe("OsController", func() {
},
Status: v1.NodeStatus{
NodeInfo: v1.NodeSystemInfo{
- OSImage: "KubeOS v2",
+ OSImage: "KubeOS v1",
},
},
}
@@ -241,6 +308,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -249,6 +317,9 @@ var _ = Describe("OsController", func() {
ObjectMeta: metav1.ObjectMeta{
Name: node1Name,
Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
},
Spec: upgradev1.OSInstanceSpec{
SysConfigs: upgradev1.SysConfigs{
@@ -261,14 +332,76 @@ var _ = Describe("OsController", func() {
}
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
createdOSIns := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v1",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ NodeStatus: values.NodeStatusIdle.String(),
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
APIVersion: "upgrade.openeuler.org/v1alpha1",
@@ -311,13 +444,21 @@ var _ = Describe("OsController", func() {
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
- configedOSIns := &upgradev1.OSInstance{}
+ configedOSIns1 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, configedOSIns1)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(configedOSIns1.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
+ Expect(configedOSIns1.Spec.SysConfigs.Version).Should(Equal("v2"))
+
+ configedOSIns2 := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, configedOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, configedOSIns2)
return err == nil
}, timeout, interval).Should(BeTrue())
- Expect(configedOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
- Expect(configedOSIns.Spec.SysConfigs.Version).Should(Equal("v2"))
+ Expect(configedOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
+ Expect(configedOSIns2.Spec.SysConfigs.Version).Should(Equal("v2"))
})
})
@@ -394,6 +535,9 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
_, ok := existingNode.Labels[values.LabelUpgrading]
Expect(ok).Should(Equal(false))
+
+ createdOS.Spec.OpsType = "test"
+ Expect(k8sClient.Update(ctx, createdOS)).Should(Succeed())
})
})
@@ -401,7 +545,7 @@ var _ = Describe("OsController", func() {
It("Should exchange .current and .next", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -430,7 +574,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
- // create OSInstance
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -454,14 +598,75 @@ var _ = Describe("OsController", func() {
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
// Check that the corresponding OSIns CR has been created
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
createdOSIns := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v1",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
// create OS CR
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
@@ -486,7 +691,13 @@ var _ = Describe("OsController", func() {
{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
},
},
- UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
+ UpgradeConfigs: upgradev1.SysConfigs{
+ Version: "v2",
+ Configs: []upgradev1.SysConfig{
+ {Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}},
+ {Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
+ },
+ },
},
}
Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
@@ -501,75 +712,66 @@ var _ = Describe("OsController", func() {
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
- osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ // check node1 osinstance
createdOSIns = &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
Expect(createdOSIns.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
+ Expect(createdOSIns.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+
+ // check node2 osinstance
+ createdOSIns2 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
+ Expect(createdOSIns2.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+
+ // check os cr spec
+ osCRLookupKey = types.NamespacedName{Name: OSName, Namespace: testNamespace}
+ createdOS = &upgradev1.OS{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOS.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOS.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
})
})
})
-func TestOSReconciler_DeleteOSInstance(t *testing.T) {
- type fields struct {
- Scheme *runtime.Scheme
- Client client.Client
- }
- kClient, _ := client.New(cfg, client.Options{Scheme: scheme.Scheme})
+func Test_deepCopySpecConfigs(t *testing.T) {
type args struct {
- e event.DeleteEvent
- q workqueue.RateLimitingInterface
+ os *upgradev1.OS
+ osinstance *upgradev1.OSInstance
+ configType string
}
tests := []struct {
- name string
- fields fields
- args args
+ name string
+ args args
+ wantErr bool
}{
{
- name: "delete osinstance",
- fields: fields{
- Scheme: nil,
- Client: kClient,
- },
+ name: "error",
args: args{
- e: event.DeleteEvent{
- Object: &upgradev1.OSInstance{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node1",
- Namespace: "test",
- },
- },
- },
- q: nil,
- },
+ os: &upgradev1.OS{},
+ osinstance: &upgradev1.OSInstance{},
+ configType: "test"},
+ wantErr: true,
},
}
- var patchList *gomonkey.Patches
- var patchDelete *gomonkey.Patches
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- r := &OSReconciler{
- Scheme: tt.fields.Scheme,
- Client: tt.fields.Client,
+ if err := deepCopySpecConfigs(tt.args.os, tt.args.osinstance, tt.args.configType); (err != nil) != tt.wantErr {
+ t.Errorf("deepCopySpecConfigs() error = %v, wantErr %v", err, tt.wantErr)
}
- patchList = gomonkey.ApplyMethodFunc(r.Client, "List", func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
- list.(*upgradev1.OSInstanceList).Items = []upgradev1.OSInstance{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node1",
- Namespace: "test",
- },
- },
- }
- return nil
- })
- patchDelete = gomonkey.ApplyMethodReturn(r.Client, "Delete", nil)
- r.DeleteOSInstance(tt.args.e, tt.args.q)
})
}
- defer patchDelete.Reset()
- defer patchList.Reset()
}
--
2.39.0