@@ -20,21 +20,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2020package restore
2121
2222import (
23+ "context"
2324 "fmt"
2425 "strconv"
2526 "strings"
27+ "testing"
2628 "time"
2729
2830 . "github.com/onsi/ginkgo/v2"
2931 . "github.com/onsi/gomega"
32+ "github.com/stretchr/testify/require"
3033 batchv1 "k8s.io/api/batch/v1"
3134 corev1 "k8s.io/api/core/v1"
3235 apierrors "k8s.io/apimachinery/pkg/api/errors"
3336 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+ "k8s.io/apimachinery/pkg/runtime"
3438 "k8s.io/apimachinery/pkg/types"
3539 ctrl "sigs.k8s.io/controller-runtime"
3640 "sigs.k8s.io/controller-runtime/pkg/client"
41+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
3742
43+ appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
3844 dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1"
3945 "github.com/apecloud/kubeblocks/pkg/constant"
4046 intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
@@ -47,6 +53,82 @@ import (
4753 viper "github.com/apecloud/kubeblocks/pkg/viperx"
4854)
4955
56+ func postReadyJobEnvValues (job * batchv1.Job , name string ) []string {
57+ var values []string
58+ for i := range job .Spec .Template .Spec .Containers [0 ].Env {
59+ env := job .Spec .Template .Spec .Containers [0 ].Env [i ]
60+ if env .Name == name {
61+ values = append (values , env .Value )
62+ }
63+ }
64+ return values
65+ }
66+
67+ func TestRestoreManagerPostReadyTargetEnv (t * testing.T ) {
68+ const (
69+ namespace = "default"
70+ clusterName = "target"
71+ componentName = "mysql"
72+ )
73+ scheme := runtime .NewScheme ()
74+ require .NoError (t , appsv1 .AddToScheme (scheme ))
75+ cluster := & appsv1.Cluster {
76+ ObjectMeta : metav1.ObjectMeta {Namespace : namespace , Name : clusterName },
77+ Spec : appsv1.ClusterSpec {Topology : "shared-nothing" },
78+ }
79+ component := & appsv1.Component {
80+ ObjectMeta : metav1.ObjectMeta {
81+ Namespace : namespace ,
82+ Name : constant .GenerateClusterComponentName (clusterName , componentName ),
83+ },
84+ Spec : appsv1.ComponentSpec {
85+ ServiceVersion : "3.3.2" ,
86+ Instances : []appsv1.InstanceTemplate {
87+ {Name : "canary" , ServiceVersion : "3.4.0" },
88+ {Name : "inherited" },
89+ },
90+ },
91+ }
92+ cli := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (cluster , component ).Build ()
93+ manager := & RestoreManager {Restore : & dpv1alpha1.Restore {}}
94+ reqCtx := intctrlutil.RequestCtx {Ctx : context .Background ()}
95+
96+ tests := []struct {
97+ name string
98+ instanceTemplate string
99+ wantVersion string
100+ }{
101+ {name : "component default" , wantVersion : "3.3.2" },
102+ {name : "instance override" , instanceTemplate : "canary" , wantVersion : "3.4.0" },
103+ {name : "instance inherits component" , instanceTemplate : "inherited" , wantVersion : "3.3.2" },
104+ }
105+ for _ , tt := range tests {
106+ t .Run (tt .name , func (t * testing.T ) {
107+ pod := & corev1.Pod {ObjectMeta : metav1.ObjectMeta {
108+ Namespace : namespace ,
109+ Name : "target-mysql-0" ,
110+ Labels : map [string ]string {
111+ constant .AppInstanceLabelKey : clusterName ,
112+ constant .KBAppComponentLabelKey : componentName ,
113+ constant .KBAppInstanceTemplateLabelKey : tt .instanceTemplate ,
114+ },
115+ }}
116+
117+ env , err := manager .postReadyTargetEnv (reqCtx , cli , pod )
118+
119+ require .NoError (t , err )
120+ require .Equal (t , []corev1.EnvVar {
121+ {Name : dptypes .DPTargetClusterTopology , Value : "shared-nothing" },
122+ {Name : dptypes .DPTargetServiceVersion , Value : tt .wantVersion },
123+ }, env )
124+ })
125+ }
126+
127+ env , err := manager .postReadyTargetEnv (reqCtx , cli , & corev1.Pod {})
128+ require .NoError (t , err )
129+ require .Empty (t , env , "non-KubeBlocks target Pods must keep their existing behavior" )
130+ }
131+
50132var _ = Describe ("RestoreManager Test" , func () {
51133
52134 cleanEnv := func () {
@@ -58,6 +140,7 @@ var _ = Describe("RestoreManager Test", func() {
58140 // namespaced
59141 testapps .ClearResources (& testCtx , generics .PodSignature , inNS , ml )
60142 testapps .ClearResources (& testCtx , generics .ClusterSignature , inNS , ml )
143+ testapps .ClearResources (& testCtx , generics .ComponentSignature , inNS , ml )
61144 testapps .ClearResourcesWithRemoveFinalizerOption (& testCtx , generics .BackupSignature , true , inNS )
62145
63146 // wait all backup to be deleted, otherwise the controller maybe create
@@ -538,9 +621,23 @@ var _ = Describe("RestoreManager Test", func() {
538621 restoreMGR , backupSet := initResources (reqCtx , 0 , false , func (f * testdp.MockRestoreFactory ) {
539622 f .SetConnectCredential (testdp .ClusterName ).SetJobActionConfig (matchLabels ).SetExecActionConfig (matchLabels )
540623 })
624+ restoreMGR .Restore .Spec .Env = append (restoreMGR .Restore .Spec .Env ,
625+ corev1.EnvVar {Name : dptypes .DPTargetClusterTopology , Value : "spoofed-topology" },
626+ corev1.EnvVar {Name : dptypes .DPTargetServiceVersion , Value : "spoofed-version" })
541627
542628 By ("create cluster to restore" )
543- testdp .NewFakeCluster (& testCtx )
629+ clusterInfo := testdp .NewFakeCluster (& testCtx )
630+ Expect (testapps .ChangeObj (& testCtx , clusterInfo .Cluster , func (cluster * appsv1.Cluster ) {
631+ cluster .Spec .Topology = "shared-nothing"
632+ })).Should (Succeed ())
633+ testapps .NewComponentFactory (testCtx .DefaultNamespace ,
634+ constant .GenerateClusterComponentName (testdp .ClusterName , testdp .ComponentName ), "test-cmpd" ).
635+ SetServiceVersion ("3.3.2" ).
636+ AddInstances (appsv1.InstanceTemplate {Name : "canary" , ServiceVersion : "3.4.0" }).
637+ Create (& testCtx )
638+ Expect (testapps .ChangeObj (& testCtx , clusterInfo .TargetPod , func (pod * corev1.Pod ) {
639+ pod .Labels [constant .KBAppInstanceTemplateLabelKey ] = "canary"
640+ })).Should (Succeed ())
544641
545642 By ("test with execAction and expect for creating 2 exec job" )
546643 target := utils .GetBackupStatusTarget (backupSet .Backup , restoreMGR .Restore .Spec .Backup .SourceTargetName )
@@ -558,6 +655,8 @@ var _ = Describe("RestoreManager Test", func() {
558655 Expect (err ).ShouldNot (HaveOccurred ())
559656 // count of job should equal to 1
560657 Expect (len (jobs )).Should (Equal (1 ))
658+ Expect (postReadyJobEnvValues (jobs [0 ], dptypes .DPTargetClusterTopology )).Should (Equal ([]string {"shared-nothing" }))
659+ Expect (postReadyJobEnvValues (jobs [0 ], dptypes .DPTargetServiceVersion )).Should (Equal ([]string {"3.4.0" }))
561660 // test timeZone transform
562661 var backupStopTimeEnv string
563662 for _ , v := range jobs [0 ].Spec .Template .Spec .Containers [0 ].Env {
0 commit comments