Skip to content

Commit f0fe7d2

Browse files
authored
CLOUDP-116155 Initial bootup with arbiters (#1024)
1 parent 9a22e28 commit f0fe7d2

File tree

5 files changed

+105
-68
lines changed

5 files changed

+105
-68
lines changed

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ e2e-gh:
121121
scripts/dev/run_e2e_gh.sh $(test)
122122

123123
cleanup-e2e:
124-
kubectl delete mdbc,all -l e2e-test=true -n ${TEST_NAMESPACE} | true
124+
kubectl delete mdbc,all,secrets -l e2e-test=true -n ${TEST_NAMESPACE} || true
125+
# Most of the tests use StatefulSets, which in turn use stable storage. In order to
126+
# avoid interleaving tests with each other, we need to drop them all.
127+
kubectl delete pvc --all || true
125128

126129
# Generate code
127130
generate: controller-gen

controllers/replica_set_controller.go

+4
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,10 @@ func (r *ReplicaSetReconciler) shouldRunInOrder(mdb mdbv1.MongoDBCommunity) bool
405405

406406
// if we are scaling up, we need to make sure the StatefulSet is scaled up first.
407407
if scale.IsScalingUp(mdb) || mdb.CurrentArbiters() < mdb.DesiredArbiters() {
408+
if scale.HasZeroReplicas(mdb) {
409+
r.log.Debug("Scaling up the ReplicaSet when there is no replicas, the Automation Config must be updated first")
410+
return true
411+
}
408412
r.log.Debug("Scaling up the ReplicaSet, the StatefulSet must be updated first")
409413
return false
410414
}

pkg/util/scale/scale.go

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func IsScalingUp(replicaSetScaler ReplicaSetScaler) bool {
4545
return replicaSetScaler.DesiredReplicas() > replicaSetScaler.CurrentReplicas() && replicaSetScaler.CurrentReplicas() != 0
4646
}
4747

48+
func HasZeroReplicas(replicaSetScaler ReplicaSetScaler) bool {
49+
return replicaSetScaler.CurrentReplicas() == 0
50+
}
51+
4852
// AnyAreStillScaling reports true if any of one the provided members is still scaling
4953
func AnyAreStillScaling(scalers ...ReplicaSetScaler) bool {
5054
for _, s := range scalers {

test/e2e/mongodbtests/mongodbtests.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func arbitersStatefulSetIsReady(mdb *mdbv1.MongoDBCommunity, opts ...wait.Config
9797
if err != nil {
9898
t.Fatal(err)
9999
}
100-
t.Logf("StatefulSet %s/%s is ready!", mdb.Namespace, mdb.Name)
100+
t.Logf("Arbiters StatefulSet %s/%s is ready!", mdb.Namespace, mdb.Name)
101101
}
102102
}
103103

@@ -327,6 +327,16 @@ func CreateMongoDBResource(mdb *mdbv1.MongoDBCommunity, ctx *e2eutil.Context) fu
327327
}
328328
}
329329

330+
// DeleteMongoDBResource deletes the MongoDB resource
331+
func DeleteMongoDBResource(mdb *mdbv1.MongoDBCommunity, ctx *e2eutil.Context) func(*testing.T) {
332+
return func(t *testing.T) {
333+
if err := e2eutil.TestClient.Delete(context.TODO(), mdb); err != nil {
334+
t.Fatal(err)
335+
}
336+
t.Logf("Deleted MongoDB resource %s/%s", mdb.Name, mdb.Namespace)
337+
}
338+
}
339+
330340
// GetConnectionStringSecret returnes the secret generated by the operator that is storing the connection string for a specific user
331341
func GetConnectionStringSecret(mdb mdbv1.MongoDBCommunity, user scram.User) corev1.Secret {
332342
secret := corev1.Secret{}

test/e2e/replica_set_arbiter/replica_set_arbiter_test.go

+82-66
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ package replica_set
22

33
import (
44
"fmt"
5-
"os"
6-
"testing"
7-
"time"
8-
9-
. "github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/mongotester"
10-
"github.com/stretchr/testify/assert"
11-
125
e2eutil "github.com/mongodb/mongodb-kubernetes-operator/test/e2e"
136
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/mongodbtests"
147
setup "github.com/mongodb/mongodb-kubernetes-operator/test/e2e/setup"
8+
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/mongotester"
159
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/wait"
10+
"github.com/stretchr/testify/assert"
11+
"os"
12+
"testing"
13+
"time"
1614
)
1715

1816
func TestMain(m *testing.M) {
@@ -23,71 +21,89 @@ func TestMain(m *testing.M) {
2321
os.Exit(code)
2422
}
2523

24+
func Test(t *testing.T) {
25+
26+
}
27+
2628
func TestReplicaSetArbiter(t *testing.T) {
2729
ctx := setup.Setup(t)
2830
defer ctx.Teardown()
2931

30-
// Invalid case 1
31-
numberArbiters := 3
32-
numberMembers := 3
33-
desiredStatus := fmt.Sprintf("error validating new Spec: number of arbiters specified (%v) is greater or equal than the number of members in the replicaset (%v). At least one member must not be an arbiter", numberArbiters, numberMembers)
34-
mdb, user := e2eutil.NewTestMongoDB(ctx, "mdb0", "")
35-
mdb.Spec.Arbiters = numberArbiters
36-
mdb.Spec.Members = numberMembers
37-
_, err := setup.GeneratePasswordForUser(ctx, user, "")
38-
if err != nil {
39-
t.Fatal(err)
32+
type args struct {
33+
numberOfArbiters int
34+
scaleArbitersTo int
35+
numberOfMembers int
36+
expectedErrorMessage string
37+
resourceName string
4038
}
41-
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
42-
t.Run("Check status for case 1", mongodbtests.StatefulSetMessageIsReceived(&mdb, ctx, desiredStatus))
43-
44-
// Invalid case 2
45-
numberArbiters = -1
46-
numberMembers = 3
47-
desiredStatus = "error validating new Spec: number of arbiters must be greater or equal than 0"
48-
mdb, user = e2eutil.NewTestMongoDB(ctx, "mdb1", "")
49-
mdb.Spec.Arbiters = numberArbiters
50-
mdb.Spec.Members = numberMembers
51-
_, err = setup.GeneratePasswordForUser(ctx, user, "")
52-
if err != nil {
53-
t.Fatal(err)
39+
tests := map[string]args{
40+
"Number of Arbiters must be less than number of nodes": {
41+
numberOfArbiters: 3,
42+
numberOfMembers: 3,
43+
expectedErrorMessage: fmt.Sprintf("error validating new Spec: number of arbiters specified (%v) is greater or equal than the number of members in the replicaset (%v). At least one member must not be an arbiter", 3, 3),
44+
resourceName: "mdb0",
45+
},
46+
"Number of Arbiters must be greater than 0": {
47+
numberOfArbiters: -1,
48+
numberOfMembers: 3,
49+
expectedErrorMessage: "error validating new Spec: number of arbiters must be greater or equal than 0",
50+
resourceName: "mdb1",
51+
},
52+
"Scaling arbiters from 0 to 1": {
53+
numberOfArbiters: 0,
54+
scaleArbitersTo: 1,
55+
numberOfMembers: 2,
56+
resourceName: "mdb2",
57+
},
58+
"Scaling Arbiters from 1 to 0": {
59+
numberOfArbiters: 1,
60+
scaleArbitersTo: 0,
61+
numberOfMembers: 3,
62+
resourceName: "mdb3",
63+
},
64+
"Arbiters can be deployed in initial bootstrap": {
65+
numberOfArbiters: 1,
66+
scaleArbitersTo: 1,
67+
numberOfMembers: 2,
68+
resourceName: "mdb4",
69+
},
5470
}
55-
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
56-
t.Run("Check status for case 2", mongodbtests.StatefulSetMessageIsReceived(&mdb, ctx, desiredStatus))
71+
for testName, _ := range tests {
72+
t.Run(testName, func(t *testing.T) {
73+
testConfig, _ := tests[testName]
74+
mdb, user := e2eutil.NewTestMongoDB(ctx, testConfig.resourceName, "")
75+
mdb.Spec.Arbiters = testConfig.numberOfArbiters
76+
mdb.Spec.Members = testConfig.numberOfMembers
77+
pwd, err := setup.GeneratePasswordForUser(ctx, user, "")
78+
if err != nil {
79+
t.Fatal(err)
80+
}
81+
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
82+
if len(testConfig.expectedErrorMessage) > 0 {
83+
t.Run("Check status", mongodbtests.StatefulSetMessageIsReceived(&mdb, ctx, testConfig.expectedErrorMessage))
84+
} else {
85+
t.Run("Check that the stateful set becomes ready", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
86+
t.Run("Check the number of arbiters", mongodbtests.AutomationConfigReplicaSetsHaveExpectedArbiters(&mdb, testConfig.numberOfArbiters))
5787

58-
numberArbiters = 0
59-
numberMembers = 3
60-
mdb, user = e2eutil.NewTestMongoDB(ctx, "mdb2", "")
61-
mdb.Spec.Arbiters = numberArbiters
62-
mdb.Spec.Members = numberMembers
63-
pwd, err := setup.GeneratePasswordForUser(ctx, user, "")
64-
if err != nil {
65-
t.Fatal(err)
66-
}
67-
68-
t.Run("Create MongoDB Resource", mongodbtests.CreateMongoDBResource(&mdb, ctx))
69-
t.Run("Check that the stateful set becomes ready", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
70-
t.Run("Check the number of arbiters", mongodbtests.AutomationConfigReplicaSetsHaveExpectedArbiters(&mdb, numberArbiters))
71-
72-
// Arbiters need to be less than regular members
73-
t.Run("Scale MongoDB Up to 2 Arbiters", mongodbtests.ScaleArbiters(&mdb, 2))
74-
t.Run("Arbiters Stateful Set Scaled Up Correctly", mongodbtests.ArbitersStatefulSetBecomesReady(&mdb))
75-
t.Run("MongoDB Reaches Running Phase", mongodbtests.MongoDBReachesRunningPhase(&mdb))
88+
if testConfig.numberOfArbiters != testConfig.scaleArbitersTo {
89+
t.Run(fmt.Sprintf("Scale Arbiters to %v", testConfig.scaleArbitersTo), mongodbtests.ScaleArbiters(&mdb, testConfig.scaleArbitersTo))
90+
t.Run("Arbiters Stateful Set Scaled Correctly", mongodbtests.ArbitersStatefulSetBecomesReady(&mdb))
91+
}
7692

77-
t.Run("Test SRV Connectivity with generated connection string secret", func(t *testing.T) {
78-
tester, err := FromResource(t, mdb)
79-
if err != nil {
80-
t.Fatal(err)
81-
}
82-
scramUser := mdb.GetScramUsers()[0]
83-
expectedCnxStr := fmt.Sprintf("mongodb+srv://%s-user:%s@%s-svc.%s.svc.cluster.local/admin?replicaSet=mdb2&ssl=false", mdb.Name, pwd, mdb.Name, mdb.Namespace)
84-
cnxStrSrv := mongodbtests.GetSrvConnectionStringForUser(mdb, scramUser)
85-
assert.Equal(t, expectedCnxStr, cnxStrSrv)
86-
tester.ConnectivitySucceeds(WithURI(cnxStrSrv))
87-
})
88-
89-
t.Run("Scale MongoDB Up to 0 Arbiters", mongodbtests.ScaleArbiters(&mdb, 0))
90-
t.Run("Arbiters Stateful Set Scaled Up Correctly", mongodbtests.ArbitersStatefulSetBecomesReady(&mdb))
91-
t.Run("MongoDB Reaches Running Phase", mongodbtests.MongoDBReachesRunningPhase(&mdb))
92-
t.Run("Check the number of arbiters", mongodbtests.AutomationConfigReplicaSetsHaveExpectedArbiters(&mdb, 0))
93+
t.Run("MongoDB Reaches Running Phase", mongodbtests.MongoDBReachesRunningPhase(&mdb))
94+
t.Run("Test SRV Connectivity with generated connection string secret", func(t *testing.T) {
95+
tester, err := mongotester.FromResource(t, mdb)
96+
if err != nil {
97+
t.Fatal(err)
98+
}
99+
scramUser := mdb.GetScramUsers()[0]
100+
expectedCnxStr := fmt.Sprintf("mongodb+srv://%s-user:%s@%s-svc.%s.svc.cluster.local/admin?replicaSet=%s&ssl=false", mdb.Name, pwd, mdb.Name, mdb.Namespace, mdb.Name)
101+
cnxStrSrv := mongodbtests.GetSrvConnectionStringForUser(mdb, scramUser)
102+
assert.Equal(t, expectedCnxStr, cnxStrSrv)
103+
tester.ConnectivitySucceeds(mongotester.WithURI(cnxStrSrv))
104+
})
105+
}
106+
t.Run("Delete MongoDB Resource", mongodbtests.DeleteMongoDBResource(&mdb, ctx))
107+
})
108+
}
93109
}

0 commit comments

Comments
 (0)