Skip to content

Commit 398a271

Browse files
authored
test(e2e): Fix flaky test for ClusterCacheInfo validation (#537)
Signed-off-by: Jayendra Parsai <[email protected]>
1 parent 8ed7e84 commit 398a271

File tree

5 files changed

+90
-78
lines changed

5 files changed

+90
-78
lines changed

test/e2e/appcache_test.go

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ import (
2929
"k8s.io/apimachinery/pkg/types"
3030
)
3131

32-
const (
33-
PrincipalName = "principal"
34-
AgentManagedName = "agent-managed"
35-
AgentAutonomousName = "agent-autonomous"
36-
)
37-
3832
type CacheTestSuite struct {
3933
fixture.BaseSuite
4034
}
@@ -48,22 +42,22 @@ func (suite *CacheTestSuite) TearDownTest() {
4842
}
4943

5044
func (suite *CacheTestSuite) SetupTest() {
51-
if !fixture.IsProcessRunning(PrincipalName) {
45+
if !fixture.IsProcessRunning(fixture.PrincipalName) {
5246
// Start the principal if it is not running and wait for it to be ready
53-
suite.Require().NoError(fixture.StartProcess(PrincipalName))
54-
fixture.CheckReadiness(suite.T(), PrincipalName)
47+
suite.Require().NoError(fixture.StartProcess(fixture.PrincipalName))
48+
fixture.CheckReadiness(suite.T(), fixture.PrincipalName)
5549
} else {
5650
// If principal is already running, verify that it is ready
57-
fixture.CheckReadiness(suite.T(), PrincipalName)
51+
fixture.CheckReadiness(suite.T(), fixture.PrincipalName)
5852
}
5953

60-
if !fixture.IsProcessRunning(AgentManagedName) {
54+
if !fixture.IsProcessRunning(fixture.AgentManagedName) {
6155
// Start the agent if it is not running and wait for it to be ready
62-
suite.Require().NoError(fixture.StartProcess(AgentManagedName))
63-
fixture.CheckReadiness(suite.T(), AgentManagedName)
56+
suite.Require().NoError(fixture.StartProcess(fixture.AgentManagedName))
57+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
6458
} else {
6559
// If agent is already running, verify that it is ready
66-
fixture.CheckReadiness(suite.T(), AgentManagedName)
60+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
6761
}
6862

6963
suite.BaseSuite.SetupTest()
@@ -113,17 +107,17 @@ func (suite *CacheTestSuite) Test_RevertDisconnectedManagedClusterChanges() {
113107

114108
// Case 1: Agent is disconnected with principal, now modify the application directly in the managed-cluster,
115109
// but changes should be reverted, to be in sync with last known state of principal application
116-
requires.NoError(fixture.StopProcess(PrincipalName))
110+
requires.NoError(fixture.StopProcess(fixture.PrincipalName))
117111
requires.Eventually(func() bool {
118-
return !fixture.IsProcessRunning(PrincipalName)
112+
return !fixture.IsProcessRunning(fixture.PrincipalName)
119113
}, 30*time.Second, 1*time.Second)
120114

121115
updateAppInfo(suite.Ctx, suite.ManagedAgentClient, agentKey, []string{"a", "b"}, requires)
122116
validateAppReverted(suite.Ctx, suite.ManagedAgentClient, &app, agentKey, requires, suite.T())
123117

124118
// Case 2: Agent is reconnected with principal and now changes done in principal should reflect in managed-cluster
125-
requires.NoError(fixture.StartProcess(PrincipalName))
126-
fixture.CheckReadiness(suite.T(), PrincipalName)
119+
requires.NoError(fixture.StartProcess(fixture.PrincipalName))
120+
fixture.CheckReadiness(suite.T(), fixture.PrincipalName)
127121

128122
updateAppInfo(suite.Ctx, suite.PrincipalClient, principalKey, []string{"a", "b"}, requires)
129123
validateAppInfoUpdated(suite.Ctx, suite.ManagedAgentClient, agentKey, []string{"a", "b"}, requires)
@@ -143,8 +137,8 @@ func (suite *CacheTestSuite) Test_CacheRecreatedOnRestart() {
143137

144138
// Case 1: Agent is restarted, now make direct changes in the managed-cluster,
145139
// but they should be reverted to be in sync with last known state of principal app
146-
fixture.RestartAgent(suite.T(), AgentManagedName)
147-
fixture.CheckReadiness(suite.T(), AgentManagedName)
140+
fixture.RestartAgent(suite.T(), fixture.AgentManagedName)
141+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
148142

149143
updateAppInfo(suite.Ctx, suite.ManagedAgentClient, agentKey, []string{"a", "b"}, requires)
150144
validateAppReverted(suite.Ctx, suite.ManagedAgentClient, &app, agentKey, requires, suite.T())
@@ -169,18 +163,18 @@ func (suite *CacheTestSuite) Test_RevertManagedClusterOfflineChanges() {
169163
// Agent in not running, but still make changes in the managed-cluster application manifest.
170164
// When agent is restarted, these changes should be reverted to be in sync with principal.
171165
requires.Eventually(func() bool {
172-
return fixture.IsProcessRunning(AgentManagedName)
166+
return fixture.IsProcessRunning(fixture.AgentManagedName)
173167
}, 60*time.Second, 1*time.Second)
174168

175-
requires.NoError(fixture.StopProcess(AgentManagedName))
169+
requires.NoError(fixture.StopProcess(fixture.AgentManagedName))
176170
requires.Eventually(func() bool {
177-
return !fixture.IsProcessRunning(AgentManagedName)
171+
return !fixture.IsProcessRunning(fixture.AgentManagedName)
178172
}, 60*time.Second, 1*time.Second)
179173

180174
updateAppInfo(suite.Ctx, suite.ManagedAgentClient, agentKey, []string{"a", "b"}, requires)
181175

182-
requires.NoError(fixture.StartProcess(AgentManagedName))
183-
fixture.CheckReadiness(suite.T(), AgentManagedName)
176+
requires.NoError(fixture.StartProcess(fixture.AgentManagedName))
177+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
184178
validateAppReverted(suite.Ctx, suite.ManagedAgentClient, &app, agentKey, requires, suite.T())
185179
}
186180

@@ -196,7 +190,7 @@ func createApp(ctx context.Context, client fixture.KubeClient, requires *require
196190
app := argoapp.Application{
197191
ObjectMeta: metav1.ObjectMeta{
198192
Name: name,
199-
Namespace: AgentManagedName,
193+
Namespace: fixture.AgentManagedName,
200194
},
201195
Spec: argoapp.ApplicationSpec{
202196
Project: "default",
@@ -206,7 +200,7 @@ func createApp(ctx context.Context, client fixture.KubeClient, requires *require
206200
Path: "kustomize-guestbook",
207201
},
208202
Destination: argoapp.ApplicationDestination{
209-
Server: "https://kubernetes.default.svc",
203+
Server: fixture.AgentClusterServerURL,
210204
Namespace: namespace,
211205
},
212206
SyncPolicy: &argoapp.SyncPolicy{

test/e2e/clusterinfo_test.go

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,31 @@ func TestClusterTestSuite(t *testing.T) {
4242
}
4343

4444
func (suite *ClusterInfoTestSuite) SetupTest() {
45-
if !fixture.IsProcessRunning(PrincipalName) {
45+
if !fixture.IsProcessRunning(fixture.PrincipalName) {
4646
// Start the principal if it is not running and wait for it to be ready
47-
suite.Require().NoError(fixture.StartProcess(PrincipalName))
48-
fixture.CheckReadiness(suite.T(), PrincipalName)
47+
suite.Require().NoError(fixture.StartProcess(fixture.PrincipalName))
48+
fixture.CheckReadiness(suite.T(), fixture.PrincipalName)
4949
} else {
5050
// If principal is already running, verify that it is ready
51-
fixture.CheckReadiness(suite.T(), PrincipalName)
51+
fixture.CheckReadiness(suite.T(), fixture.PrincipalName)
5252
}
5353

54-
if !fixture.IsProcessRunning(AgentManagedName) {
54+
if !fixture.IsProcessRunning(fixture.AgentManagedName) {
5555
// Start the agent if it is not running and wait for it to be ready
56-
suite.Require().NoError(fixture.StartProcess(AgentManagedName))
57-
fixture.CheckReadiness(suite.T(), AgentManagedName)
56+
suite.Require().NoError(fixture.StartProcess(fixture.AgentManagedName))
57+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
5858
} else {
5959
// If agent is already running, verify that it is ready
60-
fixture.CheckReadiness(suite.T(), AgentManagedName)
60+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
6161
}
6262

63-
if !fixture.IsProcessRunning(AgentAutonomousName) {
63+
if !fixture.IsProcessRunning(fixture.AgentAutonomousName) {
6464
// Start the agent if it is not running and wait for it to be ready
65-
suite.Require().NoError(fixture.StartProcess(AgentAutonomousName))
66-
fixture.CheckReadiness(suite.T(), AgentAutonomousName)
65+
suite.Require().NoError(fixture.StartProcess(fixture.AgentAutonomousName))
66+
fixture.CheckReadiness(suite.T(), fixture.AgentAutonomousName)
6767
} else {
6868
// If agent is already running, verify that it is ready
69-
fixture.CheckReadiness(suite.T(), AgentAutonomousName)
69+
fixture.CheckReadiness(suite.T(), fixture.AgentAutonomousName)
7070
}
7171

7272
suite.BaseSuite.SetupTest()
@@ -81,33 +81,33 @@ func (suite *ClusterInfoTestSuite) Test_ClusterInfo_Managed() {
8181
requires.Eventually(func() bool {
8282
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
8383
Status: appv1.ConnectionStatusSuccessful,
84-
Message: fmt.Sprintf(message, AgentManagedName, "connected"),
84+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "connected"),
8585
})
8686
}, 30*time.Second, 1*time.Second)
8787

8888
// Stop the agent
89-
err := fixture.StopProcess(AgentManagedName)
89+
err := fixture.StopProcess(fixture.AgentManagedName)
9090
requires.NoError(err)
9191

9292
// Verify that connection status is updated when agent is disconnected
9393
requires.Eventually(func() bool {
9494
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
9595
Status: appv1.ConnectionStatusFailed,
96-
Message: fmt.Sprintf(message, AgentManagedName, "disconnected"),
96+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "disconnected"),
9797
ModifiedAt: &metav1.Time{Time: time.Now()},
9898
})
9999
}, 30*time.Second, 1*time.Second)
100100

101101
// Restart the agent
102-
err = fixture.StartProcess(AgentManagedName)
102+
err = fixture.StartProcess(fixture.AgentManagedName)
103103
requires.NoError(err)
104-
fixture.CheckReadiness(suite.T(), AgentManagedName)
104+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
105105

106106
// Verify that connection status is updated again when agent is re-connected
107107
requires.Eventually(func() bool {
108108
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
109109
Status: appv1.ConnectionStatusSuccessful,
110-
Message: fmt.Sprintf(message, AgentManagedName, "connected"),
110+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "connected"),
111111
ModifiedAt: &metav1.Time{Time: time.Now()},
112112
})
113113
}, 30*time.Second, 1*time.Second)
@@ -120,33 +120,33 @@ func (suite *ClusterInfoTestSuite) Test_ClusterInfo_Autonomous() {
120120
requires.Eventually(func() bool {
121121
return fixture.HasConnectionStatus(os.Getenv(fixture.AutonomousAgentServerKey), appv1.ConnectionState{
122122
Status: appv1.ConnectionStatusSuccessful,
123-
Message: fmt.Sprintf(message, AgentAutonomousName, "connected"),
123+
Message: fmt.Sprintf(message, fixture.AgentAutonomousName, "connected"),
124124
})
125125
}, 30*time.Second, 1*time.Second)
126126

127127
// Stop the agent
128-
err := fixture.StopProcess(AgentAutonomousName)
128+
err := fixture.StopProcess(fixture.AgentAutonomousName)
129129
requires.NoError(err)
130130

131131
// Verify that connection status is updated when agent is disconnected
132132
requires.Eventually(func() bool {
133133
return fixture.HasConnectionStatus(os.Getenv(fixture.AutonomousAgentServerKey), appv1.ConnectionState{
134134
Status: appv1.ConnectionStatusFailed,
135-
Message: fmt.Sprintf(message, AgentAutonomousName, "disconnected"),
135+
Message: fmt.Sprintf(message, fixture.AgentAutonomousName, "disconnected"),
136136
ModifiedAt: &metav1.Time{Time: time.Now()},
137137
})
138138
}, 30*time.Second, 1*time.Second)
139139

140140
// Restart the agent
141-
err = fixture.StartProcess(AgentAutonomousName)
141+
err = fixture.StartProcess(fixture.AgentAutonomousName)
142142
requires.NoError(err)
143-
fixture.CheckReadiness(suite.T(), AgentAutonomousName)
143+
fixture.CheckReadiness(suite.T(), fixture.AgentAutonomousName)
144144

145145
// Verify that connection status is updated again when agent is re-connected
146146
requires.Eventually(func() bool {
147147
return fixture.HasConnectionStatus(os.Getenv(fixture.AutonomousAgentServerKey), appv1.ConnectionState{
148148
Status: appv1.ConnectionStatusSuccessful,
149-
Message: fmt.Sprintf(message, AgentAutonomousName, "connected"),
149+
Message: fmt.Sprintf(message, fixture.AgentAutonomousName, "connected"),
150150
ModifiedAt: &metav1.Time{Time: time.Now()},
151151
})
152152
}, 30*time.Second, 1*time.Second)
@@ -222,17 +222,17 @@ func (suite *ClusterInfoTestSuite) Test_ClusterCacheInfo() {
222222
requires.Eventually(func() bool {
223223
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
224224
Status: appv1.ConnectionStatusSuccessful,
225-
Message: fmt.Sprintf(message, AgentManagedName, "connected"),
225+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "connected"),
226226
})
227227
}, 30*time.Second, 1*time.Second)
228228

229229
// Step 8:
230230
// Disconnect agent and verify that connection status is changed to Failed
231-
requires.NoError(fixture.StopProcess(AgentManagedName))
231+
requires.NoError(fixture.StopProcess(fixture.AgentManagedName))
232232
requires.Eventually(func() bool {
233233
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
234234
Status: appv1.ConnectionStatusFailed,
235-
Message: fmt.Sprintf(message, AgentManagedName, "disconnected"),
235+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "disconnected"),
236236
ModifiedAt: &metav1.Time{Time: time.Now()},
237237
})
238238
}, 60*time.Second, 2*time.Second)
@@ -249,13 +249,13 @@ func (suite *ClusterInfoTestSuite) Test_ClusterCacheInfo() {
249249

250250
// Step 10:
251251
// Reconnect agent and verify that connection status and cluster cache info are updated again with correct values
252-
requires.NoError(fixture.StartProcess(AgentManagedName))
253-
fixture.CheckReadiness(suite.T(), AgentManagedName)
252+
requires.NoError(fixture.StartProcess(fixture.AgentManagedName))
253+
fixture.CheckReadiness(suite.T(), fixture.AgentManagedName)
254254

255255
requires.Eventually(func() bool {
256256
return fixture.HasConnectionStatus(os.Getenv(fixture.ManagedAgentServerKey), appv1.ConnectionState{
257257
Status: appv1.ConnectionStatusSuccessful,
258-
Message: fmt.Sprintf(message, AgentManagedName, "connected"),
258+
Message: fmt.Sprintf(message, fixture.AgentManagedName, "connected"),
259259
ModifiedAt: &metav1.Time{Time: time.Now()},
260260
})
261261
}, 60*time.Second, 2*time.Second)

test/e2e/fixture/cluster.go

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ const (
3333
PrincipalRedisServerPasswordKey = "AGENT_E2E_PRINCIPAL_REDIS_PASSWORD"
3434
AgentManagedRedisServerAddressKey = "AGENT_E2E_AGENT_MANAGED_REDIS_SERVER_ADDRESS"
3535
AgentManagedRedisServerPasswordKey = "AGENT_E2E_AGENT_MANAGED_REDIS_PASSWORD"
36+
37+
PrincipalName = "principal"
38+
AgentManagedName = "agent-managed"
39+
AgentAutonomousName = "agent-autonomous"
40+
AgentClusterServerURL = "https://kubernetes.default.svc"
3641
)
3742

3843
// HasConnectionStatus checks if the connection info for a given server matches
@@ -57,7 +62,7 @@ func HasConnectionStatus(serverName string, expected appv1.ConnectionState) bool
5762
func HasClusterCacheInfoSynced(serverName string) bool {
5863
principalClusterInfo, err := GetPrincipalClusterInfo(serverName)
5964
if err != nil {
60-
fmt.Println("HasConnectionStatus: error", err)
65+
fmt.Println("HasClusterCacheInfoSynced: error", err)
6166
return false
6267
}
6368

@@ -82,6 +87,7 @@ func HasApplicationsCount(expected int64) bool {
8287
fmt.Println("HasApplicationsCount: error", err)
8388
return false
8489
}
90+
fmt.Printf("HasApplicationsCount expected: %d, actual: %d\n", expected, agentCacheInfo.ApplicationsCount)
8591
return agentCacheInfo.ApplicationsCount == expected
8692
}
8793

@@ -100,19 +106,10 @@ func verifyConnectionModificationTime(actualTime *metav1.Time, expectedTime *met
100106

101107
// GetManagedAgentClusterInfo retrieves cluster info from managed agent's Redis server
102108
func GetManagedAgentClusterInfo() (appv1.ClusterInfo, error) {
103-
// Create Redis client and cache
104-
redisOptions := &redis.Options{Addr: os.Getenv(AgentManagedRedisServerAddressKey),
105-
Password: os.Getenv(AgentManagedRedisServerPasswordKey)}
106-
107-
redisClient := redis.NewClient(redisOptions)
108-
cache := appstatecache.NewCache(cacheutil.NewCache(
109-
cacheutil.NewRedisCache(redisClient, time.Minute, cacheutil.RedisCompressionGZip)), time.Minute)
110-
111-
clusterServer := "https://kubernetes.default.svc"
112109

113110
// Fetch cluster info from redis cache
114111
clusterInfo := appv1.ClusterInfo{}
115-
err := cache.GetClusterInfo(clusterServer, &clusterInfo)
112+
err := getCacheInstance(AgentManagedName).GetClusterInfo(AgentClusterServerURL, &clusterInfo)
116113
if err != nil {
117114
// Treat missing cache key error (means no apps exist yet) as zero-value info
118115
if err == cacheutil.ErrCacheMiss {
@@ -127,17 +124,28 @@ func GetManagedAgentClusterInfo() (appv1.ClusterInfo, error) {
127124

128125
// GetPrincipalClusterInfo retrieves cluster info from principal's Redis server
129126
func GetPrincipalClusterInfo(server string) (appv1.ClusterInfo, error) {
130-
// Create Redis client and cache
131-
redisOptions := &redis.Options{Addr: os.Getenv(PrincipalRedisServerAddressKey),
132-
Password: os.Getenv(PrincipalRedisServerPasswordKey)}
127+
var clusterInfo appv1.ClusterInfo
128+
err := getCacheInstance(PrincipalName).GetClusterInfo(server, &clusterInfo)
129+
return clusterInfo, err
130+
}
131+
132+
// getCacheInstance creates a new cache instance for the given source
133+
func getCacheInstance(source string) *appstatecache.Cache {
134+
redisOptions := &redis.Options{}
135+
switch source {
136+
case PrincipalName:
137+
redisOptions.Addr = os.Getenv(PrincipalRedisServerAddressKey)
138+
redisOptions.Password = os.Getenv(PrincipalRedisServerPasswordKey)
139+
case AgentManagedName:
140+
redisOptions.Addr = os.Getenv(AgentManagedRedisServerAddressKey)
141+
redisOptions.Password = os.Getenv(AgentManagedRedisServerPasswordKey)
142+
default:
143+
panic(fmt.Sprintf("invalid source: %s", source))
144+
}
133145

134146
redisClient := redis.NewClient(redisOptions)
135147
cache := appstatecache.NewCache(cacheutil.NewCache(
136148
cacheutil.NewRedisCache(redisClient, 0, cacheutil.RedisCompressionGZip)), 0)
137149

138-
// fetch cluster info
139-
var clusterInfo appv1.ClusterInfo
140-
err := cache.GetClusterInfo(server, &clusterInfo)
141-
142-
return clusterInfo, err
150+
return cache
143151
}

test/e2e/fixture/fixture.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (suite *BaseSuite) SetupTest() {
8787
suite.T().Log(err)
8888
}
8989
return err == nil && len(project.Annotations) > 0 && project.Annotations["created"] == now
90-
}, 10*time.Second, 1*time.Second)
90+
}, 30*time.Second, 1*time.Second)
9191

9292
suite.T().Logf("Test begun at: %v", time.Now())
9393
}
@@ -280,5 +280,15 @@ func CleanUp(ctx context.Context, principalClient KubeClient, managedAgentClient
280280
return err
281281
}
282282

283+
return resetManagedAgentClusterInfo()
284+
}
285+
286+
// resetManagedAgentClusterInfo resets the cluster info in the redis cache for the managed agent
287+
func resetManagedAgentClusterInfo() error {
288+
// Reset cluster info in redis cache
289+
if err := getCacheInstance(AgentManagedName).SetClusterInfo(AgentClusterServerURL, &argoapp.ClusterInfo{}); err != nil {
290+
fmt.Println("resetManagedAgentClusterInfo: error", err)
291+
return err
292+
}
283293
return nil
284294
}

test/e2e/fixture/toxyproxy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,5 @@ func CheckReadiness(t require.TestingT, compName string) {
123123
}
124124
defer resp.Body.Close()
125125
return resp.StatusCode == http.StatusOK
126-
}, 60*time.Second, 1*time.Second)
126+
}, 120*time.Second, 2*time.Second)
127127
}

0 commit comments

Comments
 (0)