Skip to content

Commit e097b3e

Browse files
committed
faster tests with mocks
1 parent aa1f970 commit e097b3e

10 files changed

+325
-73
lines changed

maintnotifications/e2e/config_parser_test.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,17 +1009,17 @@ func SetupTestDatabaseWithConfig(t *testing.T, ctx context.Context, dbConfig Dat
10091009
return bdbID, cleanup
10101010
}
10111011

1012-
// SetupTestDatabaseAndFactory creates a database from environment config and returns both bdbID, factory, and cleanup function
1012+
// SetupTestDatabaseAndFactory creates a database from environment config and returns both bdbID, factory, test mode config, and cleanup function
10131013
// This is the recommended way to setup tests as it ensures the client factory connects to the newly created database
10141014
//
10151015
// If REDIS_ENDPOINTS_CONFIG_PATH is not set, it will use the Docker proxy setup (localhost:7000) instead of creating a new database.
10161016
// This allows tests to work with either the real fault injector OR the Docker proxy setup.
10171017
//
10181018
// Usage:
10191019
//
1020-
// bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
1020+
// bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
10211021
// defer cleanup()
1022-
func SetupTestDatabaseAndFactory(t *testing.T, ctx context.Context, databaseName string) (bdbID int, factory *ClientFactory, cleanup func()) {
1022+
func SetupTestDatabaseAndFactory(t *testing.T, ctx context.Context, databaseName string) (bdbID int, factory *ClientFactory, testMode *TestModeConfig, cleanup func()) {
10231023
// Get environment config
10241024
envConfig, err := GetEnvConfig()
10251025
if err != nil {
@@ -1038,12 +1038,15 @@ func SetupTestDatabaseAndFactory(t *testing.T, ctx context.Context, databaseName
10381038

10391039
factory = NewClientFactory(redisConfig)
10401040

1041+
// Get proxy mock test mode config
1042+
testMode = GetTestModeConfig()
1043+
10411044
// No-op cleanup since we're not creating a database
10421045
cleanup = func() {
10431046
factory.DestroyAll()
10441047
}
10451048

1046-
return 0, factory, cleanup
1049+
return 0, factory, testMode, cleanup
10471050
}
10481051

10491052
// Get database config from environment
@@ -1108,26 +1111,29 @@ func SetupTestDatabaseAndFactory(t *testing.T, ctx context.Context, databaseName
11081111
// Create client factory with the actual config from fault injector
11091112
factory = NewClientFactory(redisConfig)
11101113

1114+
// Get real fault injector test mode config
1115+
testMode = GetTestModeConfig()
1116+
11111117
// Combined cleanup function
11121118
cleanup = func() {
11131119
factory.DestroyAll()
11141120
dbManager.Cleanup(ctx)
11151121
fiCleanup()
11161122
}
11171123

1118-
return bdbID, factory, cleanup
1124+
return bdbID, factory, testMode, cleanup
11191125
}
11201126

1121-
// SetupTestDatabaseAndFactoryWithConfig creates a database with custom config and returns both bdbID, factory, and cleanup function
1127+
// SetupTestDatabaseAndFactoryWithConfig creates a database with custom config and returns both bdbID, factory, test mode config, and cleanup function
11221128
//
11231129
// If REDIS_ENDPOINTS_CONFIG_PATH is not set, it will use the Docker proxy setup (localhost:7000) instead of creating a new database.
11241130
// This allows tests to work with either the real fault injector OR the Docker proxy setup.
11251131
//
11261132
// Usage:
11271133
//
1128-
// bdbID, factory, cleanup := SetupTestDatabaseAndFactoryWithConfig(t, ctx, "standalone", dbConfig)
1134+
// bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactoryWithConfig(t, ctx, "standalone", dbConfig)
11291135
// defer cleanup()
1130-
func SetupTestDatabaseAndFactoryWithConfig(t *testing.T, ctx context.Context, databaseName string, dbConfig DatabaseConfig) (bdbID int, factory *ClientFactory, cleanup func()) {
1136+
func SetupTestDatabaseAndFactoryWithConfig(t *testing.T, ctx context.Context, databaseName string, dbConfig DatabaseConfig) (bdbID int, factory *ClientFactory, testMode *TestModeConfig, cleanup func()) {
11311137
// Get environment config to use as template for connection details
11321138
envConfig, err := GetEnvConfig()
11331139
if err != nil {
@@ -1146,12 +1152,15 @@ func SetupTestDatabaseAndFactoryWithConfig(t *testing.T, ctx context.Context, da
11461152

11471153
factory = NewClientFactory(redisConfig)
11481154

1155+
// Get proxy mock test mode config
1156+
testMode = GetTestModeConfig()
1157+
11491158
// No-op cleanup since we're not creating a database
11501159
cleanup = func() {
11511160
factory.DestroyAll()
11521161
}
11531162

1154-
return 0, factory, cleanup
1163+
return 0, factory, testMode, cleanup
11551164
}
11561165

11571166
// Get database config from environment
@@ -1210,12 +1219,15 @@ func SetupTestDatabaseAndFactoryWithConfig(t *testing.T, ctx context.Context, da
12101219
// Create client factory with the actual config from fault injector
12111220
factory = NewClientFactory(redisConfig)
12121221

1222+
// Get real fault injector test mode config
1223+
testMode = GetTestModeConfig()
1224+
12131225
// Combined cleanup function
12141226
cleanup = func() {
12151227
factory.DestroyAll()
12161228
dbManager.Cleanup(ctx)
12171229
fiCleanup()
12181230
}
12191231

1220-
return bdbID, factory, cleanup
1232+
return bdbID, factory, testMode, cleanup
12211233
}

maintnotifications/e2e/notification_injector.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ type NotificationInjector interface {
4242

4343
// IsReal returns true if this is a real fault injector (not a mock)
4444
IsReal() bool
45+
46+
// GetTestModeConfig returns the test mode configuration for this injector
47+
GetTestModeConfig() *TestModeConfig
4548
}
4649

4750
// NewNotificationInjector creates a notification injector based on environment
@@ -310,6 +313,19 @@ func (p *ProxyNotificationInjector) IsReal() bool {
310313
return false
311314
}
312315

316+
func (p *ProxyNotificationInjector) GetTestModeConfig() *TestModeConfig {
317+
return &TestModeConfig{
318+
Mode: TestModeProxyMock,
319+
NotificationDelay: 1 * time.Second,
320+
ActionWaitTimeout: 10 * time.Second,
321+
ActionPollInterval: 500 * time.Millisecond,
322+
DatabaseReadyDelay: 1 * time.Second,
323+
ConnectionEstablishDelay: 500 * time.Millisecond,
324+
MaxClients: 1,
325+
SkipMultiClientTests: true,
326+
}
327+
}
328+
313329
func (p *ProxyNotificationInjector) InjectSMIGRATING(ctx context.Context, seqID int64, slots ...string) error {
314330
notification := formatSMigratingNotification(seqID, slots...)
315331
return p.injectNotification(notification)
@@ -449,6 +465,19 @@ func (f *FaultInjectorNotificationInjector) IsReal() bool {
449465
return true
450466
}
451467

468+
func (f *FaultInjectorNotificationInjector) GetTestModeConfig() *TestModeConfig {
469+
return &TestModeConfig{
470+
Mode: TestModeRealFaultInjector,
471+
NotificationDelay: 30 * time.Second,
472+
ActionWaitTimeout: 240 * time.Second,
473+
ActionPollInterval: 2 * time.Second,
474+
DatabaseReadyDelay: 10 * time.Second,
475+
ConnectionEstablishDelay: 2 * time.Second,
476+
MaxClients: 3,
477+
SkipMultiClientTests: false,
478+
}
479+
}
480+
452481
func (f *FaultInjectorNotificationInjector) InjectSMIGRATING(ctx context.Context, seqID int64, slots ...string) error {
453482
// For real fault injector, we trigger actual slot migration which will generate SMIGRATING
454483
// Parse slot ranges

maintnotifications/e2e/notiftracker.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,65 @@ func (a *DiagnosticsAnalysis) Print(t *testing.T) {
364364
t.Logf("-------------")
365365
t.Logf("Diagnostics Analysis completed successfully")
366366
}
367+
368+
// setupNotificationHook adds a notification hook to a cluster client
369+
func setupNotificationHook(client *redis.ClusterClient, hook maintnotifications.NotificationHook) {
370+
client.ForEachShard(context.Background(), func(ctx context.Context, nodeClient *redis.Client) error {
371+
manager := nodeClient.GetMaintNotificationsManager()
372+
if manager != nil {
373+
manager.AddNotificationHook(hook)
374+
}
375+
return nil
376+
})
377+
378+
// Also add hook to new nodes
379+
client.OnNewNode(func(nodeClient *redis.Client) {
380+
manager := nodeClient.GetMaintNotificationsManager()
381+
if manager != nil {
382+
manager.AddNotificationHook(hook)
383+
}
384+
})
385+
}
386+
387+
// setupNotificationHooks adds multiple notification hooks to a regular client
388+
func setupNotificationHooks(client redis.UniversalClient, hooks ...maintnotifications.NotificationHook) {
389+
// Try to get manager from the client
390+
var manager *maintnotifications.Manager
391+
392+
// Check if it's a regular client
393+
if regularClient, ok := client.(*redis.Client); ok {
394+
manager = regularClient.GetMaintNotificationsManager()
395+
}
396+
397+
// Check if it's a cluster client
398+
if clusterClient, ok := client.(*redis.ClusterClient); ok {
399+
// For cluster clients, add hooks to all shards
400+
clusterClient.ForEachShard(context.Background(), func(ctx context.Context, nodeClient *redis.Client) error {
401+
nodeManager := nodeClient.GetMaintNotificationsManager()
402+
if nodeManager != nil {
403+
for _, hook := range hooks {
404+
nodeManager.AddNotificationHook(hook)
405+
}
406+
}
407+
return nil
408+
})
409+
410+
// Also add hooks to new nodes
411+
clusterClient.OnNewNode(func(nodeClient *redis.Client) {
412+
nodeManager := nodeClient.GetMaintNotificationsManager()
413+
if nodeManager != nil {
414+
for _, hook := range hooks {
415+
nodeManager.AddNotificationHook(hook)
416+
}
417+
}
418+
})
419+
return
420+
}
421+
422+
// For regular clients, add hooks directly
423+
if manager != nil {
424+
for _, hook := range hooks {
425+
manager.AddNotificationHook(hook)
426+
}
427+
}
428+
}

maintnotifications/e2e/scenario_endpoint_types_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,14 @@ func TestEndpointTypesPushNotifications(t *testing.T) {
5858
for _, endpointTest := range endpointTypes {
5959
t.Run(endpointTest.name, func(t *testing.T) {
6060
// Setup: Create fresh database and client factory for THIS endpoint type test
61-
bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
61+
bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
6262
defer cleanup()
63-
t.Logf("[ENDPOINT-TYPES-%s] Created test database with bdb_id: %d", endpointTest.name, bdbID)
63+
t.Logf("[ENDPOINT-TYPES-%s] Created test database with bdb_id: %d (mode: %s)", endpointTest.name, bdbID, testMode.Mode)
64+
65+
// Skip this test if using proxy mock (requires real fault injector)
66+
if testMode.IsProxyMock() {
67+
t.Skip("Skipping endpoint type test - requires real fault injector")
68+
}
6469

6570
// Create fault injector with cleanup
6671
faultInjector, fiCleanup, err := CreateTestFaultInjectorWithCleanup()

maintnotifications/e2e/scenario_push_notifications_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@ func TestPushNotifications(t *testing.T) {
2323
defer cancel()
2424

2525
// Setup: Create fresh database and client factory for this test
26-
bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
26+
bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
2727
defer cleanup()
28-
t.Logf("[PUSH-NOTIFICATIONS] Created test database with bdb_id: %d", bdbID)
28+
t.Logf("[PUSH-NOTIFICATIONS] Created test database with bdb_id: %d (mode: %s)", bdbID, testMode.Mode)
2929

30-
// Wait for database to be fully ready
31-
time.Sleep(10 * time.Second)
30+
// Skip this test if using proxy mock (requires real fault injector)
31+
if testMode.IsProxyMock() {
32+
t.Skip("Skipping push notifications test - requires real fault injector")
33+
}
34+
35+
// Wait for database to be fully ready (mode-aware)
36+
time.Sleep(testMode.DatabaseReadyDelay)
3237

3338
var dump = true
3439
var seqIDToObserve int64

maintnotifications/e2e/scenario_stress_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@ func TestStressPushNotifications(t *testing.T) {
2323
defer cancel()
2424

2525
// Setup: Create fresh database and client factory for this test
26-
bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
26+
bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
2727
defer cleanup()
28-
t.Logf("[STRESS] Created test database with bdb_id: %d", bdbID)
28+
t.Logf("[STRESS] Created test database with bdb_id: %d (mode: %s)", bdbID, testMode.Mode)
2929

30-
// Wait for database to be fully ready
31-
time.Sleep(10 * time.Second)
30+
// Skip this test if using proxy mock (stress test requires real fault injector)
31+
if testMode.IsProxyMock() {
32+
t.Skip("Skipping stress test - requires real fault injector")
33+
}
34+
35+
// Wait for database to be fully ready (mode-aware)
36+
time.Sleep(testMode.DatabaseReadyDelay)
3237

3338
var dump = true
3439
var errorsDetected = false

maintnotifications/e2e/scenario_timeout_configs_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ func TestTimeoutConfigurationsPushNotifications(t *testing.T) {
7878
for _, timeoutTest := range timeoutConfigs {
7979
t.Run(timeoutTest.name, func(t *testing.T) {
8080
// Setup: Create fresh database and client factory for THIS timeout config test
81-
bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
81+
bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
8282
defer cleanup()
83-
t.Logf("[TIMEOUT-CONFIGS-%s] Created test database with bdb_id: %d", timeoutTest.name, bdbID)
83+
t.Logf("[TIMEOUT-CONFIGS-%s] Created test database with bdb_id: %d (mode: %s)", timeoutTest.name, bdbID, testMode.Mode)
84+
85+
// Skip this test if using proxy mock (requires real fault injector)
86+
if testMode.IsProxyMock() {
87+
t.Skip("Skipping timeout config test - requires real fault injector")
88+
}
8489

8590
// Get endpoint config from factory (now connected to new database)
8691
endpointConfig := factory.GetConfig()

maintnotifications/e2e/scenario_tls_configs_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,14 @@ func TestTLSConfigurationsPushNotifications(t *testing.T) {
7474
for _, tlsTest := range tlsConfigs {
7575
t.Run(tlsTest.name, func(t *testing.T) {
7676
// Setup: Create fresh database and client factory for THIS TLS config test
77-
bdbID, factory, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
77+
bdbID, factory, testMode, cleanup := SetupTestDatabaseAndFactory(t, ctx, "standalone")
7878
defer cleanup()
79-
t.Logf("[TLS-CONFIGS-%s] Created test database with bdb_id: %d", tlsTest.name, bdbID)
79+
t.Logf("[TLS-CONFIGS-%s] Created test database with bdb_id: %d (mode: %s)", tlsTest.name, bdbID, testMode.Mode)
80+
81+
// Skip this test if using proxy mock (requires real fault injector)
82+
if testMode.IsProxyMock() {
83+
t.Skip("Skipping TLS config test - requires real fault injector")
84+
}
8085

8186
// Get endpoint config from factory (now connected to new database)
8287
endpointConfig := factory.GetConfig()

0 commit comments

Comments
 (0)