@@ -181,6 +181,73 @@ func GetDatabaseConfig(databasesConfig EnvDatabasesConfig, databaseName string)
181181 }, nil
182182}
183183
184+ // ConvertEnvDatabaseConfigToRedisConnectionConfig converts EnvDatabaseConfig to RedisConnectionConfig
185+ func ConvertEnvDatabaseConfigToRedisConnectionConfig (dbConfig EnvDatabaseConfig ) (* RedisConnectionConfig , error ) {
186+ // Parse connection details from endpoints or raw_endpoints
187+ var host string
188+ var port int
189+
190+ if len (dbConfig .RawEndpoints ) > 0 {
191+ // Use raw_endpoints if available (for more complex configurations)
192+ endpoint := dbConfig .RawEndpoints [0 ] // Use the first endpoint
193+ host = endpoint .DNSName
194+ port = endpoint .Port
195+ } else if len (dbConfig .Endpoints ) > 0 {
196+ // Parse from endpoints URLs
197+ endpointURL , err := url .Parse (dbConfig .Endpoints [0 ])
198+ if err != nil {
199+ return nil , fmt .Errorf ("failed to parse endpoint URL %s: %w" , dbConfig .Endpoints [0 ], err )
200+ }
201+
202+ host = endpointURL .Hostname ()
203+ portStr := endpointURL .Port ()
204+ if portStr == "" {
205+ // Default ports based on scheme
206+ switch endpointURL .Scheme {
207+ case "redis" :
208+ port = 6379
209+ case "rediss" :
210+ port = 6380
211+ default :
212+ port = 6379
213+ }
214+ } else {
215+ port , err = strconv .Atoi (portStr )
216+ if err != nil {
217+ return nil , fmt .Errorf ("invalid port in endpoint URL %s: %w" , dbConfig .Endpoints [0 ], err )
218+ }
219+ }
220+
221+ // Override TLS setting based on scheme if not explicitly set
222+ if endpointURL .Scheme == "rediss" {
223+ dbConfig .TLS = true
224+ }
225+ } else {
226+ return nil , fmt .Errorf ("no endpoints found in database configuration" )
227+ }
228+
229+ var bdbId int
230+ switch dbConfig .BdbID .(type ) {
231+ case int :
232+ bdbId = dbConfig .BdbID .(int )
233+ case float64 :
234+ bdbId = int (dbConfig .BdbID .(float64 ))
235+ case string :
236+ bdbId , _ = strconv .Atoi (dbConfig .BdbID .(string ))
237+ }
238+
239+ return & RedisConnectionConfig {
240+ Host : host ,
241+ Port : port ,
242+ Username : dbConfig .Username ,
243+ Password : dbConfig .Password ,
244+ TLS : dbConfig .TLS ,
245+ BdbID : bdbId ,
246+ CertificatesLocation : dbConfig .CertificatesLocation ,
247+ Endpoints : dbConfig .Endpoints ,
248+ }, nil
249+ }
250+
184251// ClientFactory manages Redis client creation and lifecycle
185252type ClientFactory struct {
186253 config * RedisConnectionConfig
@@ -606,6 +673,7 @@ func (m *TestDatabaseManager) CreateDatabaseFromEnvConfig(ctx context.Context, e
606673}
607674
608675// CreateDatabase creates a database and waits for it to be ready
676+ // Returns the bdb_id of the created database
609677func (m * TestDatabaseManager ) CreateDatabase (ctx context.Context , dbConfig DatabaseConfig ) (int , error ) {
610678 m .t .Logf ("Creating database '%s' on port %d..." , dbConfig .Name , dbConfig .Port )
611679
@@ -650,6 +718,122 @@ func (m *TestDatabaseManager) CreateDatabase(ctx context.Context, dbConfig Datab
650718 return bdbID , nil
651719}
652720
721+ // CreateDatabaseAndGetConfig creates a database and returns both the bdb_id and the full connection config from the fault injector response
722+ // This includes endpoints, username, password, TLS settings, and raw_endpoints
723+ func (m * TestDatabaseManager ) CreateDatabaseAndGetConfig (ctx context.Context , dbConfig DatabaseConfig ) (int , EnvDatabaseConfig , error ) {
724+ m .t .Logf ("Creating database '%s' on port %d..." , dbConfig .Name , dbConfig .Port )
725+
726+ resp , err := m .faultInjector .CreateDatabase (ctx , m .clusterIndex , dbConfig )
727+ if err != nil {
728+ return 0 , EnvDatabaseConfig {}, fmt .Errorf ("failed to trigger database creation: %w" , err )
729+ }
730+
731+ m .t .Logf ("Database creation triggered. Action ID: %s" , resp .ActionID )
732+
733+ // Wait for creation to complete
734+ status , err := m .faultInjector .WaitForAction (ctx , resp .ActionID ,
735+ WithMaxWaitTime (5 * time .Minute ),
736+ WithPollInterval (5 * time .Second ))
737+ if err != nil {
738+ return 0 , EnvDatabaseConfig {}, fmt .Errorf ("failed to wait for database creation: %w" , err )
739+ }
740+
741+ if status .Status != StatusSuccess {
742+ return 0 , EnvDatabaseConfig {}, fmt .Errorf ("database creation failed: %v" , status .Error )
743+ }
744+
745+ // Extract database configuration from output
746+ var envConfig EnvDatabaseConfig
747+ if status .Output == nil {
748+ return 0 , EnvDatabaseConfig {}, fmt .Errorf ("no output in creation response" )
749+ }
750+
751+ // Extract bdb_id
752+ var bdbID int
753+ if id , ok := status .Output ["bdb_id" ].(float64 ); ok {
754+ bdbID = int (id )
755+ envConfig .BdbID = bdbID
756+ } else {
757+ return 0 , EnvDatabaseConfig {}, fmt .Errorf ("failed to extract bdb_id from creation output" )
758+ }
759+
760+ // Extract username
761+ if username , ok := status .Output ["username" ].(string ); ok {
762+ envConfig .Username = username
763+ }
764+
765+ // Extract password
766+ if password , ok := status .Output ["password" ].(string ); ok {
767+ envConfig .Password = password
768+ }
769+
770+ // Extract TLS setting
771+ if tls , ok := status .Output ["tls" ].(bool ); ok {
772+ envConfig .TLS = tls
773+ }
774+
775+ // Extract endpoints
776+ if endpoints , ok := status .Output ["endpoints" ].([]interface {}); ok {
777+ envConfig .Endpoints = make ([]string , 0 , len (endpoints ))
778+ for _ , ep := range endpoints {
779+ if epStr , ok := ep .(string ); ok {
780+ envConfig .Endpoints = append (envConfig .Endpoints , epStr )
781+ }
782+ }
783+ }
784+
785+ // Extract raw_endpoints
786+ if rawEndpoints , ok := status .Output ["raw_endpoints" ].([]interface {}); ok {
787+ envConfig .RawEndpoints = make ([]DatabaseEndpoint , 0 , len (rawEndpoints ))
788+ for _ , rawEp := range rawEndpoints {
789+ if rawEpMap , ok := rawEp .(map [string ]interface {}); ok {
790+ var dbEndpoint DatabaseEndpoint
791+
792+ // Extract addr
793+ if addr , ok := rawEpMap ["addr" ].([]interface {}); ok {
794+ dbEndpoint .Addr = make ([]string , 0 , len (addr ))
795+ for _ , a := range addr {
796+ if aStr , ok := a .(string ); ok {
797+ dbEndpoint .Addr = append (dbEndpoint .Addr , aStr )
798+ }
799+ }
800+ }
801+
802+ // Extract other fields
803+ if addrType , ok := rawEpMap ["addr_type" ].(string ); ok {
804+ dbEndpoint .AddrType = addrType
805+ }
806+ if dnsName , ok := rawEpMap ["dns_name" ].(string ); ok {
807+ dbEndpoint .DNSName = dnsName
808+ }
809+ if preferredEndpointType , ok := rawEpMap ["oss_cluster_api_preferred_endpoint_type" ].(string ); ok {
810+ dbEndpoint .OSSClusterAPIPreferredEndpointType = preferredEndpointType
811+ }
812+ if preferredIPType , ok := rawEpMap ["oss_cluster_api_preferred_ip_type" ].(string ); ok {
813+ dbEndpoint .OSSClusterAPIPreferredIPType = preferredIPType
814+ }
815+ if port , ok := rawEpMap ["port" ].(float64 ); ok {
816+ dbEndpoint .Port = int (port )
817+ }
818+ if proxyPolicy , ok := rawEpMap ["proxy_policy" ].(string ); ok {
819+ dbEndpoint .ProxyPolicy = proxyPolicy
820+ }
821+ if uid , ok := rawEpMap ["uid" ].(string ); ok {
822+ dbEndpoint .UID = uid
823+ }
824+
825+ envConfig .RawEndpoints = append (envConfig .RawEndpoints , dbEndpoint )
826+ }
827+ }
828+ }
829+
830+ m .createdBdbID = bdbID
831+ m .t .Logf ("Database created successfully with bdb_id: %d" , bdbID )
832+ m .t .Logf ("Database endpoints: %v" , envConfig .Endpoints )
833+
834+ return bdbID , envConfig , nil
835+ }
836+
653837// DeleteDatabase deletes the created database
654838func (m * TestDatabaseManager ) DeleteDatabase (ctx context.Context ) error {
655839 if m .createdBdbID == 0 {
@@ -823,65 +1007,52 @@ func SetupTestDatabaseAndFactory(t *testing.T, ctx context.Context, databaseName
8231007 t .Fatalf ("Database %s not found in configuration" , databaseName )
8241008 }
8251009
826- // Convert to DatabaseConfig to get the port
1010+ // Convert to DatabaseConfig
8271011 dbConfig , err := ConvertEnvDatabaseConfigToFaultInjectorConfig (envDbConfig , fmt .Sprintf ("e2e-test-%s-%d" , databaseName , time .Now ().Unix ()))
8281012 if err != nil {
8291013 t .Fatalf ("Failed to convert config: %v" , err )
8301014 }
8311015
832- // Create the database
833- bdbID , cleanupDB := SetupTestDatabaseWithConfig (t , ctx , dbConfig )
1016+ // Create fault injector
1017+ faultInjector , err := CreateTestFaultInjector ()
1018+ if err != nil {
1019+ t .Fatalf ("Failed to create fault injector: %v" , err )
1020+ }
8341021
835- // Update the environment config with the new database's connection details
836- // The new database uses the port we specified in dbConfig
837- newEnvConfig := envDbConfig
838- newEnvConfig .BdbID = bdbID
1022+ // Create database manager
1023+ dbManager := NewTestDatabaseManager (t , faultInjector , 0 )
8391024
840- // Update endpoints to point to the new database's port
841- // Extract host from original endpoints
842- var host string
843- var scheme string
844- if len (envDbConfig .Endpoints ) > 0 {
845- // Parse the first endpoint to get host and scheme
846- endpoint := envDbConfig .Endpoints [0 ]
847- if strings .HasPrefix (endpoint , "redis://" ) {
848- scheme = "redis"
849- host = strings .TrimPrefix (endpoint , "redis://" )
850- } else if strings .HasPrefix (endpoint , "rediss://" ) {
851- scheme = "rediss"
852- host = strings .TrimPrefix (endpoint , "rediss://" )
853- }
854- // Remove port from host if present
855- if colonIdx := strings .Index (host , ":" ); colonIdx != - 1 {
856- host = host [:colonIdx ]
857- }
1025+ // Create the database and get the actual connection config from fault injector
1026+ bdbID , newEnvConfig , err := dbManager .CreateDatabaseAndGetConfig (ctx , dbConfig )
1027+ if err != nil {
1028+ t .Fatalf ("Failed to create test database: %v" , err )
8581029 }
8591030
860- // If we couldn't extract host, use localhost as fallback
861- if host == "" {
862- host = "localhost"
863- }
864- if scheme == "" {
865- if envDbConfig .TLS {
866- scheme = "rediss"
867- } else {
868- scheme = "redis"
869- }
870- }
1031+ t .Logf ("Database created successfully:" )
1032+ t .Logf (" bdb_id: %d" , bdbID )
1033+ t .Logf (" endpoints: %v" , newEnvConfig .Endpoints )
1034+ t .Logf (" username: %s" , newEnvConfig .Username )
1035+ t .Logf (" TLS: %v" , newEnvConfig .TLS )
8711036
872- // Construct new endpoint with the new database's port
873- newEndpoint := fmt .Sprintf ("%s://%s:%d" , scheme , host , dbConfig .Port )
874- newEnvConfig .Endpoints = []string {newEndpoint }
1037+ // Use certificate location from original config if not provided by fault injector
1038+ if newEnvConfig .CertificatesLocation == "" && envDbConfig .CertificatesLocation != "" {
1039+ newEnvConfig .CertificatesLocation = envDbConfig .CertificatesLocation
1040+ }
8751041
876- t .Logf ("New database endpoint: %s (bdb_id: %d)" , newEndpoint , bdbID )
1042+ // Convert EnvDatabaseConfig to RedisConnectionConfig
1043+ redisConfig , err := ConvertEnvDatabaseConfigToRedisConnectionConfig (newEnvConfig )
1044+ if err != nil {
1045+ dbManager .Cleanup (ctx )
1046+ t .Fatalf ("Failed to convert database config: %v" , err )
1047+ }
8771048
878- // Create client factory with the updated config
879- factory = NewClientFactory (newEnvConfig )
1049+ // Create client factory with the actual config from fault injector
1050+ factory = NewClientFactory (redisConfig )
8801051
8811052 // Combined cleanup function
8821053 cleanup = func () {
8831054 factory .DestroyAll ()
884- cleanupDB ( )
1055+ dbManager . Cleanup ( ctx )
8851056 }
8861057
8871058 return bdbID , factory , cleanup
@@ -923,58 +1094,46 @@ func SetupTestDatabaseAndFactoryWithConfig(t *testing.T, ctx context.Context, da
9231094 t .Fatalf ("Database %s not found in configuration" , databaseName )
9241095 }
9251096
926- // Create the database
927- bdbID , cleanupDB := SetupTestDatabaseWithConfig (t , ctx , dbConfig )
1097+ // Create fault injector
1098+ faultInjector , err := CreateTestFaultInjector ()
1099+ if err != nil {
1100+ t .Fatalf ("Failed to create fault injector: %v" , err )
1101+ }
9281102
929- // Update the environment config with the new database's connection details
930- newEnvConfig := envDbConfig
931- newEnvConfig .BdbID = bdbID
1103+ // Create database manager
1104+ dbManager := NewTestDatabaseManager (t , faultInjector , 0 )
9321105
933- // Update endpoints to point to the new database's port
934- // Extract host from original endpoints
935- var host string
936- var scheme string
937- if len (envDbConfig .Endpoints ) > 0 {
938- // Parse the first endpoint to get host and scheme
939- endpoint := envDbConfig .Endpoints [0 ]
940- if strings .HasPrefix (endpoint , "redis://" ) {
941- scheme = "redis"
942- host = strings .TrimPrefix (endpoint , "redis://" )
943- } else if strings .HasPrefix (endpoint , "rediss://" ) {
944- scheme = "rediss"
945- host = strings .TrimPrefix (endpoint , "rediss://" )
946- }
947- // Remove port from host if present
948- if colonIdx := strings .Index (host , ":" ); colonIdx != - 1 {
949- host = host [:colonIdx ]
950- }
1106+ // Create the database and get the actual connection config from fault injector
1107+ bdbID , newEnvConfig , err := dbManager .CreateDatabaseAndGetConfig (ctx , dbConfig )
1108+ if err != nil {
1109+ t .Fatalf ("Failed to create test database: %v" , err )
9511110 }
9521111
953- // If we couldn't extract host, use localhost as fallback
954- if host == "" {
955- host = "localhost"
956- }
957- if scheme == "" {
958- if envDbConfig .TLS {
959- scheme = "rediss"
960- } else {
961- scheme = "redis"
962- }
963- }
1112+ t .Logf ("Database created successfully:" )
1113+ t .Logf (" bdb_id: %d" , bdbID )
1114+ t .Logf (" endpoints: %v" , newEnvConfig .Endpoints )
1115+ t .Logf (" username: %s" , newEnvConfig .Username )
1116+ t .Logf (" TLS: %v" , newEnvConfig .TLS )
9641117
965- // Construct new endpoint with the new database's port
966- newEndpoint := fmt .Sprintf ("%s://%s:%d" , scheme , host , dbConfig .Port )
967- newEnvConfig .Endpoints = []string {newEndpoint }
1118+ // Use certificate location from original config if not provided by fault injector
1119+ if newEnvConfig .CertificatesLocation == "" && envDbConfig .CertificatesLocation != "" {
1120+ newEnvConfig .CertificatesLocation = envDbConfig .CertificatesLocation
1121+ }
9681122
969- t .Logf ("New database endpoint: %s (bdb_id: %d)" , newEndpoint , bdbID )
1123+ // Convert EnvDatabaseConfig to RedisConnectionConfig
1124+ redisConfig , err := ConvertEnvDatabaseConfigToRedisConnectionConfig (newEnvConfig )
1125+ if err != nil {
1126+ dbManager .Cleanup (ctx )
1127+ t .Fatalf ("Failed to convert database config: %v" , err )
1128+ }
9701129
971- // Create client factory with the updated config
972- factory = NewClientFactory (newEnvConfig )
1130+ // Create client factory with the actual config from fault injector
1131+ factory = NewClientFactory (redisConfig )
9731132
9741133 // Combined cleanup function
9751134 cleanup = func () {
9761135 factory .DestroyAll ()
977- cleanupDB ( )
1136+ dbManager . Cleanup ( ctx )
9781137 }
9791138
9801139 return bdbID , factory , cleanup
0 commit comments