Skip to content

Commit cb8f250

Browse files
authored
Increase Stability of FCV tests (#550)
1 parent acc4b4f commit cb8f250

File tree

6 files changed

+85
-26
lines changed

6 files changed

+85
-26
lines changed

api/v1/mongodbcommunity_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ type Authentication struct {
339339
// +optional
340340
// +kubebuilder:default:=true
341341
// +nullable
342-
IgnoreUnknownUsers *bool `json:"ignoreUnknownUsers"`
342+
IgnoreUnknownUsers *bool `json:"ignoreUnknownUsers,omitempty"`
343343
}
344344

345345
// +kubebuilder:validation:Enum=SCRAM

test/e2e/feature_compatibility_version/feature_compatibility_version_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/wait"
10+
911
. "github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/mongotester"
1012

1113
e2eutil "github.com/mongodb/mongodb-kubernetes-operator/test/e2e"
@@ -49,7 +51,7 @@ func TestFeatureCompatibilityVersion(t *testing.T) {
4951
t.Run("MongoDB is reachable while version is upgraded", func(t *testing.T) {
5052
defer tester.StartBackgroundConnectivityTest(t, time.Second*10)()
5153
t.Run("Test Version can be upgraded", mongodbtests.ChangeVersion(&mdb, "4.2.6"))
52-
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
54+
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
5355
})
5456

5557
t.Run("Test Basic Connectivity after upgrade has completed", tester.ConnectivitySucceeds())
@@ -59,7 +61,7 @@ func TestFeatureCompatibilityVersion(t *testing.T) {
5961
t.Run("MongoDB is reachable while version is downgraded", func(t *testing.T) {
6062
defer tester.StartBackgroundConnectivityTest(t, time.Second*10)()
6163
t.Run("Test Version can be downgraded", mongodbtests.ChangeVersion(&mdb, "4.0.6"))
62-
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
64+
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
6365
})
6466

6567
t.Run("Test FeatureCompatibilityVersion, after downgrade, is 4.0", tester.HasFCV("4.0", 3))

test/e2e/feature_compatibility_version_upgrade/feature_compatibility_version_upgrade_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/wait"
10+
911
"github.com/mongodb/mongodb-kubernetes-operator/test/e2e/util/mongotester"
1012

1113
mdbv1 "github.com/mongodb/mongodb-kubernetes-operator/api/v1"
@@ -51,7 +53,7 @@ func TestFeatureCompatibilityVersionUpgrade(t *testing.T) {
5153
t.Run("MongoDB is reachable", func(t *testing.T) {
5254
defer tester.StartBackgroundConnectivityTest(t, time.Second*10)()
5355
t.Run("Test Version can be upgraded", mongodbtests.ChangeVersion(&mdb, "4.2.6"))
54-
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
56+
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
5557
t.Run("Test Basic Connectivity after upgrade has completed", tester.ConnectivitySucceeds())
5658
})
5759

@@ -64,7 +66,7 @@ func TestFeatureCompatibilityVersionUpgrade(t *testing.T) {
6466
})
6567
assert.NoError(t, err)
6668
})
67-
t.Run("Stateful Set Reaches Ready State", mongodbtests.StatefulSetBecomesReady(&mdb))
69+
t.Run("Stateful Set Reaches Ready State", mongodbtests.StatefulSetBecomesReady(&mdb, wait.Timeout(20*time.Minute)))
6870
t.Run("MongoDB Reaches Running Phase", mongodbtests.MongoDBReachesRunningPhase(&mdb))
6971
})
7072
t.Run("Test FeatureCompatibilityVersion, after upgrade, is 4.2", tester.HasFCV("4.2", 3))

test/e2e/mongodbtests/mongodbtests.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,32 @@ func SkipTestIfLocal(t *testing.T, msg string, f func(t *testing.T)) {
3333

3434
// StatefulSetBecomesReady ensures that the underlying stateful set
3535
// reaches the running state.
36-
func StatefulSetBecomesReady(mdb *mdbv1.MongoDBCommunity) func(t *testing.T) {
37-
return statefulSetIsReady(mdb, time.Second*15, time.Minute*12)
36+
func StatefulSetBecomesReady(mdb *mdbv1.MongoDBCommunity, opts ...wait.Configuration) func(t *testing.T) {
37+
defaultOpts := []wait.Configuration{
38+
wait.RetryInterval(time.Second * 15),
39+
wait.Timeout(time.Minute * 15),
40+
}
41+
defaultOpts = append(defaultOpts, opts...)
42+
return statefulSetIsReady(mdb, defaultOpts...)
3843
}
3944

4045
// StatefulSetBecomesUnready ensures the underlying stateful set reaches
4146
// the unready state.
42-
func StatefulSetBecomesUnready(mdb *mdbv1.MongoDBCommunity) func(t *testing.T) {
43-
return statefulSetIsNotReady(mdb, time.Second*15, time.Minute*12)
47+
func StatefulSetBecomesUnready(mdb *mdbv1.MongoDBCommunity, opts ...wait.Configuration) func(t *testing.T) {
48+
defaultOpts := []wait.Configuration{
49+
wait.RetryInterval(time.Second * 15),
50+
wait.Timeout(time.Minute * 15),
51+
}
52+
defaultOpts = append(defaultOpts, opts...)
53+
return statefulSetIsNotReady(mdb, defaultOpts...)
4454
}
4555

4656
// StatefulSetIsReadyAfterScaleDown ensures that a replica set is scaled down correctly
4757
// note: scaling down takes considerably longer than scaling up due the readiness probe
4858
// failure threshold being high
4959
func StatefulSetIsReadyAfterScaleDown(mdb *mdbv1.MongoDBCommunity) func(t *testing.T) {
5060
return func(t *testing.T) {
51-
err := wait.ForStatefulSetToBeReadyAfterScaleDown(t, mdb, time.Second*60, time.Minute*45)
61+
err := wait.ForStatefulSetToBeReadyAfterScaleDown(t, mdb, wait.RetryInterval(time.Second*60), wait.Timeout(time.Minute*45))
5262
if err != nil {
5363
t.Fatal(err)
5464
}
@@ -58,9 +68,9 @@ func StatefulSetIsReadyAfterScaleDown(mdb *mdbv1.MongoDBCommunity) func(t *testi
5868

5969
// StatefulSetIsReady ensures that the underlying stateful set
6070
// reaches the running state
61-
func statefulSetIsReady(mdb *mdbv1.MongoDBCommunity, interval time.Duration, timeout time.Duration) func(t *testing.T) {
71+
func statefulSetIsReady(mdb *mdbv1.MongoDBCommunity, opts ...wait.Configuration) func(t *testing.T) {
6272
return func(t *testing.T) {
63-
err := wait.ForStatefulSetToBeReady(t, mdb, interval, timeout)
73+
err := wait.ForStatefulSetToBeReady(t, mdb, opts...)
6474
if err != nil {
6575
t.Fatal(err)
6676
}
@@ -69,9 +79,9 @@ func statefulSetIsReady(mdb *mdbv1.MongoDBCommunity, interval time.Duration, tim
6979
}
7080

7181
// statefulSetIsNotReady ensures that the underlying stateful set reaches the unready state.
72-
func statefulSetIsNotReady(mdb *mdbv1.MongoDBCommunity, interval time.Duration, timeout time.Duration) func(t *testing.T) {
82+
func statefulSetIsNotReady(mdb *mdbv1.MongoDBCommunity, opts ...wait.Configuration) func(t *testing.T) {
7383
return func(t *testing.T) {
74-
err := wait.ForStatefulSetToBeUnready(t, mdb, interval, timeout)
84+
err := wait.ForStatefulSetToBeUnready(t, mdb, opts...)
7585
if err != nil {
7686
t.Fatal(err)
7787
}
@@ -138,7 +148,7 @@ func ConnectionStringSecretsAreConfigured(mdb *mdbv1.MongoDBCommunity, expectedO
138148
// resource has the correct Update Strategy
139149
func StatefulSetHasUpdateStrategy(mdb *mdbv1.MongoDBCommunity, strategy appsv1.StatefulSetUpdateStrategyType) func(t *testing.T) {
140150
return func(t *testing.T) {
141-
err := wait.ForStatefulSetToHaveUpdateStrategy(t, mdb, strategy, time.Second*15, time.Minute*8)
151+
err := wait.ForStatefulSetToHaveUpdateStrategy(t, mdb, strategy, wait.RetryInterval(time.Second*15), wait.Timeout(time.Minute*8))
142152
if err != nil {
143153
t.Fatal(err)
144154
}

test/e2e/util/wait/wait.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,44 +60,48 @@ func ForStatefulSetToExist(stsName string, retryInterval, timeout time.Duration,
6060

6161
// ForStatefulSetToHaveUpdateStrategy waits until all replicas of the StatefulSet with the given name
6262
// have reached the ready status
63-
func ForStatefulSetToHaveUpdateStrategy(t *testing.T, mdb *mdbv1.MongoDBCommunity, strategy appsv1.StatefulSetUpdateStrategyType, retryInterval, timeout time.Duration) error {
64-
return waitForStatefulSetCondition(t, mdb, retryInterval, timeout, func(sts appsv1.StatefulSet) bool {
63+
func ForStatefulSetToHaveUpdateStrategy(t *testing.T, mdb *mdbv1.MongoDBCommunity, strategy appsv1.StatefulSetUpdateStrategyType, opts ...Configuration) error {
64+
options := newOptions(opts...)
65+
return waitForStatefulSetCondition(t, mdb, options, func(sts appsv1.StatefulSet) bool {
6566
return sts.Spec.UpdateStrategy.Type == strategy
6667
})
6768
}
6869

6970
// ForStatefulSetToBeReady waits until all replicas of the StatefulSet with the given name
7071
// have reached the ready status
71-
func ForStatefulSetToBeReady(t *testing.T, mdb *mdbv1.MongoDBCommunity, retryInterval, timeout time.Duration) error {
72-
return waitForStatefulSetCondition(t, mdb, retryInterval, timeout, func(sts appsv1.StatefulSet) bool {
72+
func ForStatefulSetToBeReady(t *testing.T, mdb *mdbv1.MongoDBCommunity, opts ...Configuration) error {
73+
options := newOptions(opts...)
74+
return waitForStatefulSetCondition(t, mdb, options, func(sts appsv1.StatefulSet) bool {
7375
return statefulset.IsReady(sts, mdb.Spec.Members)
7476
})
7577
}
7678

7779
// ForStatefulSetToBeUnready waits until all replicas of the StatefulSet with the given name
7880
// is not ready.
79-
func ForStatefulSetToBeUnready(t *testing.T, mdb *mdbv1.MongoDBCommunity, retryInterval, timeout time.Duration) error {
80-
return waitForStatefulSetCondition(t, mdb, retryInterval, timeout, func(sts appsv1.StatefulSet) bool {
81+
func ForStatefulSetToBeUnready(t *testing.T, mdb *mdbv1.MongoDBCommunity, opts ...Configuration) error {
82+
options := newOptions(opts...)
83+
return waitForStatefulSetCondition(t, mdb, options, func(sts appsv1.StatefulSet) bool {
8184
return !statefulset.IsReady(sts, mdb.Spec.Members)
8285
})
8386
}
8487

8588
// ForStatefulSetToBeReadyAfterScaleDown waits for just the ready replicas to be correct
8689
// and does not account for the updated replicas
87-
func ForStatefulSetToBeReadyAfterScaleDown(t *testing.T, mdb *mdbv1.MongoDBCommunity, retryInterval, timeout time.Duration) error {
88-
return waitForStatefulSetCondition(t, mdb, retryInterval, timeout, func(sts appsv1.StatefulSet) bool {
90+
func ForStatefulSetToBeReadyAfterScaleDown(t *testing.T, mdb *mdbv1.MongoDBCommunity, opts ...Configuration) error {
91+
options := newOptions(opts...)
92+
return waitForStatefulSetCondition(t, mdb, options, func(sts appsv1.StatefulSet) bool {
8993
return int32(mdb.Spec.Members) == sts.Status.ReadyReplicas
9094
})
9195
}
9296

93-
func waitForStatefulSetCondition(t *testing.T, mdb *mdbv1.MongoDBCommunity, retryInterval, timeout time.Duration, condition func(set appsv1.StatefulSet) bool) error {
94-
_, err := ForStatefulSetToExist(mdb.Name, retryInterval, timeout, mdb.Namespace)
97+
func waitForStatefulSetCondition(t *testing.T, mdb *mdbv1.MongoDBCommunity, waitOpts Options, condition func(set appsv1.StatefulSet) bool) error {
98+
_, err := ForStatefulSetToExist(mdb.Name, waitOpts.RetryInterval, waitOpts.Timeout, mdb.Namespace)
9599
if err != nil {
96100
return errors.Errorf("error waiting for stateful set to be created: %s", err)
97101
}
98102

99103
sts := appsv1.StatefulSet{}
100-
return wait.Poll(retryInterval, timeout, func() (done bool, err error) {
104+
return wait.Poll(waitOpts.RetryInterval, waitOpts.Timeout, func() (done bool, err error) {
101105
err = e2eutil.TestClient.Get(context.TODO(), mdb.NamespacedName(), &sts)
102106
if err != nil {
103107
return false, err

test/e2e/util/wait/wait_options.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package wait
2+
3+
import "time"
4+
5+
type Configuration func(*Options)
6+
7+
// Options holds values which can be configured when waiting for specific confitions.
8+
type Options struct {
9+
RetryInterval time.Duration
10+
Timeout time.Duration
11+
}
12+
13+
// RetryInterval specifies the RetryInterval
14+
func RetryInterval(retryInterval time.Duration) Configuration {
15+
return func(options *Options) {
16+
options.RetryInterval = retryInterval
17+
}
18+
}
19+
20+
// Timeout specifies the Timeout
21+
func Timeout(timeout time.Duration) Configuration {
22+
return func(options *Options) {
23+
options.Timeout = timeout
24+
}
25+
}
26+
27+
// newOptions returns an Options that has been configured with default values.
28+
func newOptions(fns ...Configuration) Options {
29+
defaults := defaultStatefulSetReadinessOptions()
30+
for _, fn := range fns {
31+
fn(&defaults)
32+
}
33+
return defaults
34+
}
35+
36+
func defaultStatefulSetReadinessOptions() Options {
37+
return Options{
38+
RetryInterval: time.Second * 15,
39+
Timeout: time.Minute * 12,
40+
}
41+
}

0 commit comments

Comments
 (0)