diff --git a/tests/NRedisStack.Tests/Core Commands/CoreTests.cs b/tests/NRedisStack.Tests/Core Commands/CoreTests.cs index 45856478..cf330786 100644 --- a/tests/NRedisStack.Tests/Core Commands/CoreTests.cs +++ b/tests/NRedisStack.Tests/Core Commands/CoreTests.cs @@ -231,7 +231,7 @@ public void TestBZMPopMultiplexerTimeout() var configurationOptions = new ConfigurationOptions(); configurationOptions.SyncTimeout = 1000; - using var redis = redisFixture.CustomRedis(configurationOptions, out _); + using var redis = redisFixture.GetConnectionById(configurationOptions, "standalone"); var db = redis.GetDatabase(null); db.Execute("FLUSHALL"); @@ -246,7 +246,7 @@ public async Task TestBZMPopMultiplexerTimeoutAsync() var configurationOptions = new ConfigurationOptions(); configurationOptions.SyncTimeout = 1000; - await using var redis = redisFixture.CustomRedis(configurationOptions, out _); + await using var redis = redisFixture.GetConnectionById(configurationOptions, "standalone"); var db = redis.GetDatabase(null); db.Execute("FLUSHALL"); diff --git a/tests/NRedisStack.Tests/RedisFixture.cs b/tests/NRedisStack.Tests/RedisFixture.cs index 81aca9ab..04e76897 100644 --- a/tests/NRedisStack.Tests/RedisFixture.cs +++ b/tests/NRedisStack.Tests/RedisFixture.cs @@ -1,13 +1,54 @@ using StackExchange.Redis; +using System.Text.Json; namespace NRedisStack.Tests; +public class EndpointConfig +{ + public List? endpoints { get; set; } + + public bool tls { get; set; } + + public string? password { get; set; } + + public int? bdb_id { get; set; } + + public object? raw_endpoints { get; set; } + + public ConnectionMultiplexer CreateConnection(ConfigurationOptions configurationOptions) + { + configurationOptions.EndPoints.Clear(); + + foreach (var endpoint in endpoints!) + { + configurationOptions.EndPoints.Add(endpoint); + } + + if (password != null) + { + configurationOptions.Password = password; + } + + // TODO(imalinovskiy): Add support for TLS + // TODO(imalinovskiy): Add support for Discovery/Sentinel API + + return ConnectionMultiplexer.Connect(configurationOptions); + } +} + + public class RedisFixture : IDisposable { // Set the environment variable to specify your own alternate host and port: private readonly string redisStandalone = Environment.GetEnvironmentVariable("REDIS") ?? "localhost:6379"; private readonly string? redisCluster = Environment.GetEnvironmentVariable("REDIS_CLUSTER"); private readonly string? numRedisClusterNodesEnv = Environment.GetEnvironmentVariable("NUM_REDIS_CLUSTER_NODES"); + + private readonly string defaultEndpointId = Environment.GetEnvironmentVariable("REDIS_DEFAULT_ENDPOINT_ID") ?? "standalone"; + private readonly string? redisEndpointsPath = Environment.GetEnvironmentVariable("REDIS_ENDPOINTS_CONFIG_PATH"); + private Dictionary redisEndpoints = new(); + + public bool isEnterprise = Environment.GetEnvironmentVariable("IS_ENTERPRISE") == "true"; public bool isOSSCluster; @@ -18,7 +59,42 @@ public RedisFixture() AsyncTimeout = 10000, SyncTimeout = 10000 }; - Redis = Connect(clusterConfig, out isOSSCluster); + + if (redisEndpointsPath != null && File.Exists(redisEndpointsPath)) + { + string json = File.ReadAllText(redisEndpointsPath); + var parsedEndpoints = JsonSerializer.Deserialize>(json); + + redisEndpoints = parsedEndpoints ?? throw new Exception("Failed to parse the Redis endpoints configuration."); + } + else + { + redisEndpoints.Add("standalone", + new EndpointConfig { endpoints = new List { redisStandalone } }); + + if (redisCluster != null) + { + string[] parts = redisCluster!.Split(':'); + string host = parts[0]; + int startPort = int.Parse(parts[1]); + + var endpoints = new List(); + int numRedisClusterNodes = int.Parse(numRedisClusterNodesEnv!); + for (int i = 0; i < numRedisClusterNodes; i++) + { + endpoints.Add($"{host}:{startPort + i}"); + } + + redisEndpoints.Add("cluster", + new EndpointConfig { endpoints = endpoints }); + + // Set the default endpoint to the cluster to keep the tests consistent + defaultEndpointId = "cluster"; + isOSSCluster = true; + } + } + + Redis = GetConnectionById(clusterConfig, defaultEndpointId); } public void Dispose() @@ -28,39 +104,13 @@ public void Dispose() public ConnectionMultiplexer Redis { get; } - public ConnectionMultiplexer CustomRedis(ConfigurationOptions configurationOptions, out bool isOssCluster) + public ConnectionMultiplexer GetConnectionById(ConfigurationOptions configurationOptions, string id) { - return Connect(configurationOptions, out isOssCluster); - } - - private ConnectionMultiplexer Connect(ConfigurationOptions configurationOptions, out bool isOssCluster) - { - // Redis Cluster - if (redisCluster != null && numRedisClusterNodesEnv != null) + if (!redisEndpoints.ContainsKey(id)) { - // Split to host and port - string[] parts = redisCluster!.Split(':'); - string host = parts[0]; - int startPort = int.Parse(parts[1]); - - var endpoints = new EndPointCollection(); // TODO: check if needed - - configurationOptions.EndPoints.Clear(); - int numRedisClusterNodes = int.Parse(numRedisClusterNodesEnv!); - for (int i = 0; i < numRedisClusterNodes; i++) - { - configurationOptions.EndPoints.Add(host, startPort + i); - } - - isOssCluster = true; - return ConnectionMultiplexer.Connect(configurationOptions); + throw new Exception($"The connection with id '{id}' is not configured."); } - // Redis Standalone - configurationOptions.EndPoints.Clear(); - configurationOptions.EndPoints.Add($"{redisStandalone}"); - - isOssCluster = false; - return ConnectionMultiplexer.Connect(configurationOptions); + return redisEndpoints[id].CreateConnection(configurationOptions); } } \ No newline at end of file