@@ -2,57 +2,136 @@ package operator
22
33import (
44 "context"
5+ "fmt"
6+ "testing"
7+
8+ "github.com/stretchr/testify/assert"
9+ "github.com/stretchr/testify/require"
10+ "go.uber.org/zap"
11+ "sigs.k8s.io/controller-runtime/pkg/client"
12+ "sigs.k8s.io/controller-runtime/pkg/client/interceptor"
13+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
14+
15+ appsv1 "k8s.io/api/apps/v1"
16+
517 mdbv1 "github.com/mongodb/mongodb-kubernetes/api/v1/mdb"
618 "github.com/mongodb/mongodb-kubernetes/controllers/om"
719 "github.com/mongodb/mongodb-kubernetes/controllers/operator/mock"
820 kubernetesClient "github.com/mongodb/mongodb-kubernetes/mongodb-community-operator/pkg/kube/client"
921 "github.com/mongodb/mongodb-kubernetes/pkg/images"
1022 "github.com/mongodb/mongodb-kubernetes/pkg/kube"
1123 "github.com/mongodb/mongodb-kubernetes/pkg/util"
12- "github.com/stretchr/testify/assert"
13- "sigs.k8s.io/controller-runtime/pkg/client"
14- "sigs.k8s.io/controller-runtime/pkg/reconcile"
15- "testing"
1624)
1725
18- // NedDefaultMultiReplicaSetBuilder
26+ func init () {
27+ logger , _ := zap .NewDevelopment ()
28+ zap .ReplaceGlobals (logger )
29+ }
30+
31+ var multiClusters = []string {"api1.kube.com" , "api2.kube.com" , "api3.kube.com" }
1932
2033func TestCreateMultiClusterReplicaSet (t * testing.T ) {
2134 ctx := context .Background ()
22- rs := mdbv1 .NewDefaultMultiReplicaSetBuilder ().Build ()
2335
24- reconciler , client , _ , _ := defaultMultiClusterReplicaSetReconciler (ctx , nil , "" , "" , mrs )
25- checkMultiReplicaSetReconcileSuccessful (ctx , t , reconciler , rs , client , false )
36+ rs := mdbv1 .NewDefaultMultiReplicaSetBuilder ().
37+ SetClusterSpectList (multiClusters ).
38+ Build ()
39+
40+ reconciler , kubeClient , memberClients , omConnectionFactory := defaultMultiClusterReplicaSetReconciler (ctx , nil , "" , "" , rs )
41+ checkMultiReplicaSetReconcileSuccessful (ctx , t , reconciler , rs , kubeClient , false )
42+
43+ // Verify StatefulSets exist in each member cluster
44+ for i , clusterName := range multiClusters {
45+ memberClient := memberClients [clusterName ]
46+ sts := appsv1.StatefulSet {}
47+ stsName := fmt .Sprintf ("%s-%d" , rs .Name , i )
48+ err := memberClient .Get (ctx , kube .ObjectKey (rs .Namespace , stsName ), & sts )
49+ require .NoError (t , err , "StatefulSet should exist in cluster %s" , clusterName )
50+ assert .Equal (t , int32 (1 ), * sts .Spec .Replicas , "Replicas in %s" , clusterName )
51+ }
52+
53+ // Verify OM automation config has all processes
54+ processes := omConnectionFactory .GetConnection ().(* om.MockedOmConnection ).GetProcesses ()
55+ assert .Len (t , processes , 3 )
2656}
2757
28- func checkMultiReplicaSetReconcileSuccessful (ctx context.Context , t * testing.T , reconciler reconcile.Reconciler , m * mdbv1.MongoDB , client client.Client , shouldRequeue bool ) {
58+ // Helper functions below
59+
60+ func checkMultiReplicaSetReconcileSuccessful (
61+ ctx context.Context ,
62+ t * testing.T ,
63+ reconciler reconcile.Reconciler ,
64+ m * mdbv1.MongoDB ,
65+ client client.Client ,
66+ shouldRequeue bool ,
67+ ) {
2968 err := client .Update (ctx , m )
3069 assert .NoError (t , err )
3170
3271 result , e := reconciler .Reconcile (ctx , requestFromObject (m ))
3372 assert .NoError (t , e )
73+
3474 if shouldRequeue {
3575 assert .True (t , result .Requeue || result .RequeueAfter > 0 )
3676 } else {
3777 assert .Equal (t , reconcile.Result {RequeueAfter : util .TWENTY_FOUR_HOURS }, result )
3878 }
3979
40- // fetch the last updates as the reconciliation loop can update the mdb resource.
4180 err = client .Get (ctx , kube .ObjectKey (m .Namespace , m .Name ), m )
4281 assert .NoError (t , err )
4382}
4483
45- func multiClusterReplicaSetReconciler (ctx context.Context , imageUrls images.ImageUrls , initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion string , m * mdbv1.MongoDB ) (* ReconcileMongoDbReplicaSet , kubernetesClient.Client , map [string ]client.Client , * om.CachedOMConnectionFactory ) {
46- kubeClient , omConnectionFactory := mock .NewDefaultFakeClient (m )
47- memberClusterMap := getFakeMultiClusterMap (omConnectionFactory )
48- return newReplicaSetReconciler (ctx , kubeClient , imageUrls , initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion , false , false , memberClusterMap , omConnectionFactory .GetConnectionFunc ), kubeClient , memberClusterMap , omConnectionFactory
84+ func multiClusterReplicaSetReconciler (
85+ ctx context.Context ,
86+ imageUrls images.ImageUrls ,
87+ initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion string ,
88+ rs * mdbv1.MongoDB ,
89+ ) (* ReconcileMongoDbReplicaSet , kubernetesClient.Client , map [string ]client.Client , * om.CachedOMConnectionFactory ) {
90+ kubeClient , omConnectionFactory := mock .NewDefaultFakeClient (rs )
91+ memberClusterMap := getMockMultiClusterMap (omConnectionFactory )
92+
93+ return newReplicaSetReconciler (
94+ ctx ,
95+ kubeClient ,
96+ imageUrls ,
97+ initDatabaseNonStaticImageVersion ,
98+ databaseNonStaticImageVersion ,
99+ false ,
100+ false ,
101+ memberClusterMap ,
102+ omConnectionFactory .GetConnectionFunc ,
103+ ), kubeClient , memberClusterMap , omConnectionFactory
49104}
50105
51- func defaultMultiClusterReplicaSetReconciler (ctx context.Context , imageUrls images.ImageUrls , initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion string , rs * mdbv1.MongoDB ) (* ReconcileMongoDbReplicaSet , kubernetesClient.Client , map [string ]client.Client , * om.CachedOMConnectionFactory ) {
52- multiReplicaSetController , client , clusterMap , omConnectionFactory := multiClusterReplicaSetReconciler (ctx , imageUrls , initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion , rs )
106+ func defaultMultiClusterReplicaSetReconciler (
107+ ctx context.Context ,
108+ imageUrls images.ImageUrls ,
109+ initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion string ,
110+ rs * mdbv1.MongoDB ,
111+ ) (* ReconcileMongoDbReplicaSet , kubernetesClient.Client , map [string ]client.Client , * om.CachedOMConnectionFactory ) {
112+ multiReplicaSetController , client , clusterMap , omConnectionFactory := multiClusterReplicaSetReconciler (
113+ ctx , imageUrls , initDatabaseNonStaticImageVersion , databaseNonStaticImageVersion , rs ,
114+ )
115+
53116 omConnectionFactory .SetPostCreateHook (func (connection om.Connection ) {
54- connection .(* om.MockedOmConnection ).Hostnames = calculateHostNamesForExternalDomains ( rs )
117+ connection .(* om.MockedOmConnection ).Hostnames = nil
55118 })
56119
57120 return multiReplicaSetController , client , clusterMap , omConnectionFactory
58121}
122+
123+ // getMockMultiClusterMap simulates multiple K8s clusters using fake clients
124+ func getMockMultiClusterMap (omConnectionFactory * om.CachedOMConnectionFactory ) map [string ]client.Client {
125+ clientMap := make (map [string ]client.Client )
126+
127+ for _ , clusterName := range multiClusters {
128+ fakeClientBuilder := mock .NewEmptyFakeClientBuilder ()
129+ fakeClientBuilder .WithInterceptorFuncs (interceptor.Funcs {
130+ Get : mock .GetFakeClientInterceptorGetFunc (omConnectionFactory , true , true ),
131+ })
132+
133+ clientMap [clusterName ] = kubernetesClient .NewClient (fakeClientBuilder .Build ())
134+ }
135+
136+ return clientMap
137+ }
0 commit comments