1
+ from operator import truediv
1
2
from typing import List
2
3
3
4
import kubernetes
4
5
import pytest
6
+ from kubetester import create_or_update_configmap , read_configmap , try_load , wait_until , random_k8s_name
5
7
from kubetester .automation_config_tester import AutomationConfigTester
6
8
from kubetester .certs_mongodb_multi import create_multi_cluster_mongodb_tls_certs
7
9
from kubetester .kubetester import fixture as yaml_fixture
16
18
RESOURCE_NAME = "multi-replica-set"
17
19
BUNDLE_SECRET_NAME = f"prefix-{ RESOURCE_NAME } -cert"
18
20
21
+ @pytest .fixture (scope = "module" )
22
+ def project_name_prefix (namespace : str ) -> str :
23
+ return random_k8s_name (f"{ namespace } -project-" )
24
+
25
+ @pytest .fixture (scope = "module" )
26
+ def new_project_configmap (
27
+ namespace : str ,
28
+ project_name_prefix : str
29
+ ) -> str :
30
+ cm = read_configmap (namespace = namespace , name = "my-project" )
31
+ project_name = f"{ project_name_prefix } -new-project"
32
+ return create_or_update_configmap (
33
+ namespace = namespace ,
34
+ name = project_name ,
35
+ data = {
36
+ "baseUrl" : cm ["baseUrl" ],
37
+ "projectName" : project_name ,
38
+ "orgId" : cm ["orgId" ],
39
+ },
40
+ )
41
+
19
42
20
43
@pytest .fixture (scope = "module" )
21
44
def mongodb_multi_unmarshalled (
@@ -28,7 +51,7 @@ def mongodb_multi_unmarshalled(
28
51
resource = MongoDBMulti .from_yaml (yaml_fixture ("mongodb-multi.yaml" ), RESOURCE_NAME , namespace )
29
52
resource .set_version (custom_mdb_version )
30
53
# ensure certs are created for the members during scale up
31
- resource ["spec" ]["clusterSpecList" ] = cluster_spec_list (member_cluster_names , [2 , 1 , 2 ])
54
+ resource ["spec" ]["clusterSpecList" ] = cluster_spec_list (member_cluster_names , [3 , 1 , 2 ])
32
55
resource ["spec" ]["security" ] = {
33
56
"certsSecretPrefix" : "prefix" ,
34
57
"tls" : {
@@ -58,9 +81,14 @@ def server_certs(
58
81
59
82
@pytest .fixture (scope = "module" )
60
83
def mongodb_multi (mongodb_multi_unmarshalled : MongoDBMulti , server_certs : str ) -> MongoDBMulti :
84
+ if try_load (mongodb_multi_unmarshalled ):
85
+ return mongodb_multi_unmarshalled
86
+
61
87
# remove the last element, we are only starting with 2 clusters we will scale up the 3rd one later.
62
88
mongodb_multi_unmarshalled ["spec" ]["clusterSpecList" ].pop ()
63
- return mongodb_multi_unmarshalled .update ()
89
+ # remove one member from the first cluster to start with 2 members
90
+ mongodb_multi_unmarshalled ["spec" ]["clusterSpecList" ][0 ]["members" ] = 2
91
+ return mongodb_multi_unmarshalled
64
92
65
93
66
94
@pytest .mark .e2e_multi_cluster_scale_up_cluster
@@ -70,6 +98,7 @@ def test_deploy_operator(multi_cluster_operator: Operator):
70
98
71
99
@pytest .mark .e2e_multi_cluster_scale_up_cluster
72
100
def test_create_mongodb_multi (mongodb_multi : MongoDBMulti ):
101
+ mongodb_multi .update ()
73
102
mongodb_multi .assert_reaches_phase (Phase .Running , timeout = 600 )
74
103
75
104
@@ -97,7 +126,6 @@ def test_ops_manager_has_been_updated_correctly_before_scaling():
97
126
98
127
@pytest .mark .e2e_multi_cluster_scale_up_cluster
99
128
def test_scale_mongodb_multi (mongodb_multi : MongoDBMulti , member_cluster_clients : List [MultiClusterClient ]):
100
- mongodb_multi .load ()
101
129
mongodb_multi ["spec" ]["clusterSpecList" ].append (
102
130
{"members" : 2 , "clusterName" : member_cluster_clients [2 ].cluster_name }
103
131
)
@@ -111,22 +139,8 @@ def test_statefulsets_have_been_scaled_up_correctly(
111
139
mongodb_multi : MongoDBMulti ,
112
140
member_cluster_clients : List [MultiClusterClient ],
113
141
):
114
- statefulsets = mongodb_multi .read_statefulsets (member_cluster_clients )
115
-
116
- assert len (statefulsets ) == 3
117
-
118
- cluster_one_client = member_cluster_clients [0 ]
119
- cluster_one_sts = statefulsets [cluster_one_client .cluster_name ]
120
- assert cluster_one_sts .status .ready_replicas == 2
121
-
122
- cluster_two_client = member_cluster_clients [1 ]
123
- cluster_two_sts = statefulsets [cluster_two_client .cluster_name ]
124
- assert cluster_two_sts .status .ready_replicas == 1
125
-
126
- cluster_three_client = member_cluster_clients [2 ]
127
- cluster_three_sts = statefulsets [cluster_three_client .cluster_name ]
128
- assert cluster_three_sts .status .ready_replicas == 2
129
142
143
+ wait_until (sts_are_ready (mongodb_multi , member_cluster_clients , [2 , 1 , 2 ]), timeout = 60 )
130
144
131
145
@pytest .mark .e2e_multi_cluster_scale_up_cluster
132
146
def test_ops_manager_has_been_updated_correctly_after_scaling ():
@@ -139,3 +153,60 @@ def test_ops_manager_has_been_updated_correctly_after_scaling():
139
153
def test_replica_set_is_reachable (mongodb_multi : MongoDBMulti , ca_path : str ):
140
154
tester = mongodb_multi .tester ()
141
155
tester .assert_connectivity (opts = [with_tls (use_tls = True , ca_path = ca_path )])
156
+
157
+
158
+ # From here on, the tests are for verifying that we can change the project of the MongoDBMulti resource even with
159
+ # non-sequential member ids in the replicaset.
160
+
161
+
162
+ @pytest .mark .e2e_multi_cluster_scale_up_cluster
163
+ def test_scale_up_first_cluster (
164
+ mongodb_multi : MongoDBMulti ,
165
+ member_cluster_clients : List [MultiClusterClient ],
166
+ ):
167
+ # Scale up the first cluster to 3 members. This will lead to non-sequential member ids in the replicaset.
168
+ # multi-replica-set-0-0 : 0
169
+ # multi-replica-set-0-1 : 1
170
+ # multi-replica-set-0-2 : 5
171
+ # multi-replica-set-1-0 : 2
172
+ # multi-replica-set-2-0 : 3
173
+ # multi-replica-set-2-1 : 4
174
+
175
+ mongodb_multi ["spec" ]["clusterSpecList" ][0 ]["members" ] = 3
176
+ mongodb_multi .update ()
177
+
178
+
179
+ wait_until (sts_are_ready (mongodb_multi , member_cluster_clients , [3 ,1 ,2 ]), timeout = 600 )
180
+ mongodb_multi .assert_reaches_phase (Phase .Running , timeout = 600 )
181
+
182
+
183
+ @pytest .mark .e2e_multi_cluster_scale_up_cluster
184
+ def test_change_project (mongodb_multi : MongoDBMulti , new_project_configmap : str ):
185
+ oldRsMembers = mongodb_multi .get_automation_config_tester ().get_replica_set_members (mongodb_multi .name )
186
+
187
+ mongodb_multi ["spec" ]["opsManager" ]["configMapRef" ]["name" ] = new_project_configmap
188
+ mongodb_multi .update ()
189
+
190
+ mongodb_multi .assert_abandons_phase (phase = Phase .Running , timeout = 300 )
191
+ mongodb_multi .assert_reaches_phase (phase = Phase .Running , timeout = 600 )
192
+
193
+ newRsMembers = mongodb_multi .get_automation_config_tester ().get_replica_set_members (mongodb_multi .name )
194
+
195
+ # Assert that the replica set member ids have not changed after changing the project.
196
+ assert oldRsMembers == newRsMembers
197
+
198
+
199
+ def sts_are_ready (mdb : MongoDBMulti , member_cluster_clients : List [MultiClusterClient ], members : List [int ]):
200
+ def fn ():
201
+ statefulsets = mdb .read_statefulsets (member_cluster_clients )
202
+
203
+ assert len (statefulsets ) == len (members )
204
+
205
+ for i , mcc in enumerate (member_cluster_clients ):
206
+ cluster_sts = statefulsets [mcc .cluster_name ]
207
+ if cluster_sts .status .ready_replicas != members [i ]:
208
+ return False
209
+
210
+ return True
211
+
212
+ return fn
0 commit comments