From e60eac3321b42643751f5d893cb188b04904c76b Mon Sep 17 00:00:00 2001 From: Igor Malinovskyi Date: Tue, 30 Apr 2024 10:44:19 +0200 Subject: [PATCH 1/3] Load Redis test endpoints from config file or env vars --- .../Core Commands/CoreTests.cs | 4 +- tests/NRedisStack.Tests/RedisFixture.cs | 116 +++++++++++++----- 2 files changed, 85 insertions(+), 35 deletions(-) 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..a4169c6b 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() @@ -27,40 +103,14 @@ 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 From ce4e7698fb8e1da827b10c59c5b3dcb82b5e299c Mon Sep 17 00:00:00 2001 From: Igor Malinovskyi Date: Tue, 30 Apr 2024 14:01:21 +0200 Subject: [PATCH 2/3] Fix formatting --- tests/NRedisStack.Tests/RedisFixture.cs | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/NRedisStack.Tests/RedisFixture.cs b/tests/NRedisStack.Tests/RedisFixture.cs index a4169c6b..04e76897 100644 --- a/tests/NRedisStack.Tests/RedisFixture.cs +++ b/tests/NRedisStack.Tests/RedisFixture.cs @@ -6,32 +6,32 @@ 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); } } @@ -43,12 +43,12 @@ public class RedisFixture : IDisposable 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; @@ -59,7 +59,7 @@ public RedisFixture() AsyncTimeout = 10000, SyncTimeout = 10000 }; - + if (redisEndpointsPath != null && File.Exists(redisEndpointsPath)) { string json = File.ReadAllText(redisEndpointsPath); @@ -82,18 +82,18 @@ public RedisFixture() int numRedisClusterNodes = int.Parse(numRedisClusterNodesEnv!); for (int i = 0; i < numRedisClusterNodes; i++) { - endpoints.Add($"{host}:{startPort+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); } @@ -103,14 +103,14 @@ public void Dispose() } public ConnectionMultiplexer Redis { get; } - + public ConnectionMultiplexer GetConnectionById(ConfigurationOptions configurationOptions, string id) { if (!redisEndpoints.ContainsKey(id)) { throw new Exception($"The connection with id '{id}' is not configured."); } - + return redisEndpoints[id].CreateConnection(configurationOptions); } } \ No newline at end of file From 15cadc129c4ff62537334eee9d0c317e988db16a Mon Sep 17 00:00:00 2001 From: atakavci Date: Fri, 4 Oct 2024 17:09:50 +0300 Subject: [PATCH 3/3] add IsTargetConnectionExist to help skipping some tests --- tests/NRedisStack.Tests/RedisFixture.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/NRedisStack.Tests/RedisFixture.cs b/tests/NRedisStack.Tests/RedisFixture.cs index 04e76897..0a145e85 100644 --- a/tests/NRedisStack.Tests/RedisFixture.cs +++ b/tests/NRedisStack.Tests/RedisFixture.cs @@ -113,4 +113,9 @@ public ConnectionMultiplexer GetConnectionById(ConfigurationOptions configuratio return redisEndpoints[id].CreateConnection(configurationOptions); } + + public bool IsTargetConnectionExist(string id) + { + return redisEndpoints.ContainsKey(id); + } } \ No newline at end of file