diff --git a/docs/Configuration.md b/docs/Configuration.md
index 96e4b5bae..6062a56db 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -72,11 +72,11 @@ var conn = ConnectionMultiplexer.Connect("contoso5.redis.cache.windows.net,ssl=t
The `ConfigurationOptions` object has a wide range of properties, all of which are fully documented in intellisense. Some of the more common options to use include:
| Configuration string | `ConfigurationOptions` | Default | Meaning |
-| ---------------------- | ---------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
+| ---------------------- | ---------------------- |------------------------------| --------------------------------------------------------------------------------------------------------- |
| abortConnect={bool} | `AbortOnConnectFail` | `true` (`false` on Azure) | If true, `Connect` will not create a connection while no servers are available |
| allowAdmin={bool} | `AllowAdmin` | `false` | Enables a range of commands that are considered risky |
| channelPrefix={string} | `ChannelPrefix` | `null` | Optional channel prefix for all pub/sub operations |
-| checkCertificateRevocation={bool} | `CheckCertificateRevocation` | `true` | A Boolean value that specifies whether the certificate revocation list is checked during authentication. |
+| checkCertificateRevocation={bool} | `CheckCertificateRevocation` | `true` | A Boolean value that specifies whether the certificate revocation list is checked during authentication. |
| connectRetry={int} | `ConnectRetry` | `3` | The number of times to repeat connect attempts during initial `Connect` |
| connectTimeout={int} | `ConnectTimeout` | `5000` | Timeout (ms) for connect operations |
| configChannel={string} | `ConfigurationChannel` | `__Booksleeve_MasterChanged` | Broadcast channel name for communicating configuration changes |
@@ -95,7 +95,7 @@ The `ConfigurationOptions` object has a wide range of properties, all of which a
| syncTimeout={int} | `SyncTimeout` | `5000` | Time (ms) to allow for synchronous operations |
| asyncTimeout={int} | `AsyncTimeout` | `SyncTimeout` | Time (ms) to allow for asynchronous operations |
| tiebreaker={string} | `TieBreaker` | `__Booksleeve_TieBreak` | Key to use for selecting a server in an ambiguous primary scenario |
-| version={string} | `DefaultVersion` | (`4.0` in Azure, else `2.0`) | Redis version level (useful when the server does not make this available) |
+| version={string} | `DefaultVersion` | (`7.4` in AMR, else `6.0`) | Redis version level (useful when the server does not make this available) |
| tunnel={string} | `Tunnel` | `null` | Tunnel for connections (use `http:{proxy url}` for "connect"-based proxy server) |
| setlib={bool} | `SetClientLibrary` | `true` | Whether to attempt to use `CLIENT SETINFO` to set the library name/version on the connection |
| protocol={string} | `Protocol` | `null` | Redis protocol to use; see section below |
diff --git a/src/StackExchange.Redis/Configuration/DefaultOptionsProvider.cs b/src/StackExchange.Redis/Configuration/DefaultOptionsProvider.cs
index f560c8ce4..613a092b4 100644
--- a/src/StackExchange.Redis/Configuration/DefaultOptionsProvider.cs
+++ b/src/StackExchange.Redis/Configuration/DefaultOptionsProvider.cs
@@ -140,7 +140,10 @@ public static DefaultOptionsProvider GetProvider(EndPoint endpoint)
///
/// The server version to assume.
///
- public virtual Version DefaultVersion => RedisFeatures.v3_0_0;
+ public virtual Version DefaultVersion => BaseDefaultVersion;
+
+ // this exists primarily to be queryable from tests
+ internal static Version BaseDefaultVersion = RedisFeatures.v6_0_0;
///
/// Controls how often the connection heartbeats. A heartbeat includes:
diff --git a/src/StackExchange.Redis/ConfigurationOptions.cs b/src/StackExchange.Redis/ConfigurationOptions.cs
index a3da692ef..31df3cc42 100644
--- a/src/StackExchange.Redis/ConfigurationOptions.cs
+++ b/src/StackExchange.Redis/ConfigurationOptions.cs
@@ -1194,23 +1194,13 @@ public RedisProtocol? Protocol
internal bool TryResp3()
{
+ // if Protocol specified: fine, otherwise lean on the server version
var protocol = Protocol;
- // note: deliberately leaving the IsAvailable duplicated to use short-circuit
-
- // if (protocol is null)
- // {
- // // if not specified, lean on the server version and whether HELLO is available
- // return new RedisFeatures(DefaultVersion).Resp3 && CommandMap.IsAvailable(RedisCommand.HELLO);
- // }
- // else
- // ^^^ left for context; originally our intention was to auto-enable RESP3 by default *if* the server version
- // is >= 6; however, it turns out (see extensive conversation here https://github.com/StackExchange/StackExchange.Redis/pull/2396)
- // that tangential undocumented API breaks were made at the same time; this means that even if we fix every
- // edge case in the library itself, the break is still visible to external callers via Execute[Async]; with an
- // abundance of caution, we are therefore making RESP3 explicit opt-in only for now; we may revisit this in a major
- {
- return protocol.GetValueOrDefault() >= RedisProtocol.Resp3 && CommandMap.IsAvailable(RedisCommand.HELLO);
- }
+ bool use3 = protocol is null
+ ? new RedisFeatures(DefaultVersion).Resp3
+ : protocol.GetValueOrDefault() >= RedisProtocol.Resp3;
+ // either way, it requires HELLO
+ return use3 && CommandMap.IsAvailable(RedisCommand.HELLO);
}
internal static bool TryParseRedisProtocol(string? value, out RedisProtocol protocol)
diff --git a/tests/StackExchange.Redis.Tests/ConfigTests.cs b/tests/StackExchange.Redis.Tests/ConfigTests.cs
index 1e9f791f5..55dcc5ce7 100644
--- a/tests/StackExchange.Redis.Tests/ConfigTests.cs
+++ b/tests/StackExchange.Redis.Tests/ConfigTests.cs
@@ -6,6 +6,7 @@
using System.Net;
using System.Net.Sockets;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Text;
using System.Text.RegularExpressions;
@@ -13,6 +14,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using StackExchange.Redis.Configuration;
+using StackExchange.Redis.Tests.Helpers;
using Xunit;
namespace StackExchange.Redis.Tests;
@@ -20,7 +22,31 @@ namespace StackExchange.Redis.Tests;
[RunPerProtocol]
public class ConfigTests(ITestOutputHelper output, SharedConnectionFixture fixture) : TestBase(output, fixture)
{
- public Version DefaultVersion = new(3, 0, 0);
+ private static Version BaseDefaultVersion => DefaultOptionsProvider.BaseDefaultVersion;
+
+ private static void ApplyTestDefaults(ConfigurationOptions options, bool applyProtocol = true)
+ {
+ if (applyProtocol) options.Protocol = TestContext.Current.GetProtocol();
+ }
+
+ private static string RemoveTestDefaults(string configurationString)
+ {
+ var pattern = TestContext.Current.GetProtocol() switch
+ {
+ RedisProtocol.Resp2 => ",protocol=resp2(?=,|$)",
+ RedisProtocol.Resp3 => ",protocol=resp3(?=,|$)",
+ _ => null,
+ };
+ return pattern is null
+ ? configurationString
+ : Regex.Replace(configurationString, pattern, "");
+ }
+ private static ConfigurationOptions Parse(string configuration, bool applyProtocol = true)
+ {
+ var options = ConfigurationOptions.Parse(configuration);
+ ApplyTestDefaults(options, applyProtocol);
+ return options;
+ }
[Fact]
public void ExpectedFields()
@@ -92,14 +118,14 @@ orderby name
[Fact]
public void SslProtocols_SingleValue()
{
- var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls12");
+ var options = Parse("myhost,sslProtocols=Tls12");
Assert.Equal(SslProtocols.Tls12, options.SslProtocols.GetValueOrDefault());
}
[Fact]
public void SslProtocols_MultipleValues()
{
- var options = ConfigurationOptions.Parse("myhost,sslProtocols=Tls12|Tls13");
+ var options = Parse("myhost,sslProtocols=Tls12|Tls13");
Assert.Equal(SslProtocols.Tls12 | SslProtocols.Tls13, options.SslProtocols.GetValueOrDefault());
}
@@ -109,7 +135,7 @@ public void SslProtocols_MultipleValues()
[InlineData("", true)]
public void ConfigurationOption_CheckCertificateRevocation(string conString, bool expectedValue)
{
- var options = ConfigurationOptions.Parse($"host,{conString}");
+ var options = Parse($"host,{conString}");
Assert.Equal(expectedValue, options.CheckCertificateRevocation);
var toString = options.ToString();
Assert.Contains(conString, toString, StringComparison.CurrentCultureIgnoreCase);
@@ -122,14 +148,14 @@ public void SslProtocols_UsingIntegerValue()
// .NET framework version (e.g. .NET 4.0) doesn't define an enum value (e.g. Tls11)
// but the OS has been patched with support
const int integerValue = (int)(SslProtocols.Tls12 | SslProtocols.Tls13);
- var options = ConfigurationOptions.Parse("myhost,sslProtocols=" + integerValue);
+ var options = Parse("myhost,sslProtocols=" + integerValue);
Assert.Equal(SslProtocols.Tls12 | SslProtocols.Tls13, options.SslProtocols.GetValueOrDefault());
}
[Fact]
public void SslProtocols_InvalidValue()
{
- Assert.Throws(() => ConfigurationOptions.Parse("myhost,sslProtocols=InvalidSslProtocol"));
+ Assert.Throws(() => Parse("myhost,sslProtocols=InvalidSslProtocol"));
}
[Theory]
@@ -144,7 +170,7 @@ public void SslProtocols_InvalidValue()
public void ConfigurationOptionsDefaultForAzure(string hostAndPort, bool sslShouldBeEnabled)
{
Version defaultAzureVersion = new(6, 0, 0);
- var options = ConfigurationOptions.Parse(hostAndPort);
+ var options = Parse(hostAndPort);
Assert.True(options.DefaultVersion.Equals(defaultAzureVersion));
Assert.False(options.AbortOnConnectFail);
Assert.Equal(sslShouldBeEnabled, options.Ssl);
@@ -163,7 +189,7 @@ public void ConfigurationOptionsDefaultForAzure(string hostAndPort, bool sslShou
public void ConfigurationOptionsDefaultForAzureManagedRedis(string hostAndPort, bool sslShouldBeEnabled)
{
Version defaultAzureManagedRedisVersion = new(7, 4, 0);
- var options = ConfigurationOptions.Parse(hostAndPort);
+ var options = Parse(hostAndPort);
Assert.True(options.DefaultVersion.Equals(defaultAzureManagedRedisVersion));
Assert.False(options.AbortOnConnectFail);
Assert.Equal(sslShouldBeEnabled, options.Ssl);
@@ -174,17 +200,20 @@ public void ConfigurationOptionsDefaultForAzureManagedRedis(string hostAndPort,
[InlineData("contoso.redis.azure.net:10000", RedisProtocol.Resp3, true)] // default
[InlineData("contoso.redis.azure.net:10000,protocol=resp2", RedisProtocol.Resp2, false)] // opt-out
[InlineData("contoso.redis.azure.net:10000,protocol=resp3", RedisProtocol.Resp3, true)] // opt-in
+ [InlineData("contoso.redis.azure.net:10000,version=5", RedisProtocol.Resp3, true)] // low version *ignored* (provider wins)
// azure redis cache, no overrides (we expect this to change in v3)
- [InlineData("contoso.redis.cache.windows.net:6380", null, false)] // default
+ [InlineData("contoso.redis.cache.windows.net:6380", null, true)] // default
[InlineData("contoso.redis.cache.windows.net:6380,protocol=resp2", RedisProtocol.Resp2, false)] // opt-out
[InlineData("contoso.redis.cache.windows.net:6380,protocol=resp3", RedisProtocol.Resp3, true)] // opt-in
+ [InlineData("contoso.redis.cache.windows.net:6380,version=5", null, false)] // low version means resp2
// arbitrary endpoint (we expect this to change in v3)
- [InlineData("myserver:6379", null, false)] // default
+ [InlineData("myserver:6379", null, true)] // default
[InlineData("myserver:6379,protocol=resp2", RedisProtocol.Resp2, false)] // opt-out
[InlineData("myserver:6379,protocol=resp3", RedisProtocol.Resp3, true)] // opt-in
+ [InlineData("myserver:6379,version=5", null, false)] // low version means resp2
public void CorrectRespProtocol(string config, RedisProtocol? expected, bool useResp3)
{
- var options = ConfigurationOptions.Parse(config);
+ var options = Parse(config, applyProtocol: false);
Assert.Equal(expected, options.Protocol);
Assert.Equal(useResp3, options.TryResp3());
}
@@ -192,7 +221,7 @@ public void CorrectRespProtocol(string config, RedisProtocol? expected, bool use
[Fact]
public void ConfigurationOptionsForAzureWhenSpecified()
{
- var options = ConfigurationOptions.Parse("contoso.redis.cache.windows.net,abortConnect=true, version=2.1.1");
+ var options = Parse("contoso.redis.cache.windows.net,abortConnect=true, version=2.1.1");
Assert.True(options.DefaultVersion.Equals(new Version(2, 1, 1)));
Assert.True(options.AbortOnConnectFail);
}
@@ -213,8 +242,8 @@ public void ConfigurationOptionsForAzureWhenSpecified()
[InlineData("contoso.redis.azure.net:")] // AMR host name with missing port
public void ConfigurationOptionsDefaultForNonAzure(string hostAndPort)
{
- var options = ConfigurationOptions.Parse(hostAndPort);
- Assert.True(options.DefaultVersion.Equals(DefaultVersion));
+ var options = Parse(hostAndPort);
+ Assert.True(options.DefaultVersion.Equals(BaseDefaultVersion));
Assert.True(options.AbortOnConnectFail);
Assert.False(options.Ssl);
}
@@ -223,7 +252,7 @@ public void ConfigurationOptionsDefaultForNonAzure(string hostAndPort)
public void ConfigurationOptionsDefaultWhenNoEndpointsSpecifiedYet()
{
var options = new ConfigurationOptions();
- Assert.True(options.DefaultVersion.Equals(DefaultVersion));
+ Assert.True(options.DefaultVersion.Equals(BaseDefaultVersion));
Assert.True(options.AbortOnConnectFail);
}
@@ -234,7 +263,7 @@ public void ConfigurationOptionsSyncTimeout()
var options = new ConfigurationOptions();
Assert.Equal(5000, options.SyncTimeout);
- options = ConfigurationOptions.Parse("syncTimeout=20");
+ options = Parse("syncTimeout=20");
Assert.Equal(20, options.SyncTimeout);
}
@@ -245,7 +274,7 @@ public void ConfigurationOptionsSyncTimeout()
[InlineData("[2a01:9820:1:24::1:1]:6379", AddressFamily.InterNetworkV6, "2a01:9820:1:24::1:1", 6379)]
public void ConfigurationOptionsIPv6Parsing(string configString, AddressFamily family, string address, int port)
{
- var options = ConfigurationOptions.Parse(configString);
+ var options = Parse(configString);
Assert.Single(options.EndPoints);
var ep = Assert.IsType(options.EndPoints[0]);
Assert.Equal(family, ep.AddressFamily);
@@ -258,14 +287,14 @@ public void CanParseAndFormatUnixDomainSocket()
{
const string ConfigString = "!/some/path,allowAdmin=True";
#if NETFRAMEWORK
- var ex = Assert.Throws(() => ConfigurationOptions.Parse(ConfigString));
+ var ex = Assert.Throws(() => Parse(ConfigString));
Assert.Equal("Unix domain sockets require .NET Core 3 or above", ex.Message);
#else
- var config = ConfigurationOptions.Parse(ConfigString);
+ var config = Parse(ConfigString);
Assert.True(config.AllowAdmin);
var ep = Assert.IsType(Assert.Single(config.EndPoints));
Assert.Equal("/some/path", ep.ToString());
- Assert.Equal(ConfigString, config.ToString());
+ Assert.Equal(ConfigString, RemoveTestDefaults(config.ToString()));
#endif
}
@@ -281,6 +310,7 @@ public async Task TalkToNonsenseServer()
},
ConnectTimeout = 200,
};
+ ApplyTestDefaults(config);
var log = new StringWriter();
await using (var conn = ConnectionMultiplexer.Connect(config, log))
{
@@ -292,7 +322,7 @@ public async Task TalkToNonsenseServer()
[Fact]
public async Task TestManualHeartbeat()
{
- var options = ConfigurationOptions.Parse(GetConfiguration());
+ var options = Parse(GetConfiguration());
options.HeartbeatInterval = TimeSpan.FromMilliseconds(100);
await using var conn = await ConnectionMultiplexer.ConnectAsync(options);
@@ -598,7 +628,7 @@ public void EndpointIteratorIsReliableOverChanges()
[InlineData("myDNS:myPort,password=myPassword,abortConnect=false,ssl=true,sslProtocols=Tls12 ", SslProtocols.Tls12)]
public void ParseTlsWithoutTrailingComma(string configString, SslProtocols expected)
{
- var config = ConfigurationOptions.Parse(configString);
+ var config = Parse(configString);
Assert.Equal(expected, config.SslProtocols);
}
@@ -611,7 +641,7 @@ public void ParseTlsWithoutTrailingComma(string configString, SslProtocols expec
[InlineData("foo,proxy=epoxy", "Keyword 'proxy' requires a proxy value; the value 'epoxy' is not recognised.", "proxy")]
public void ConfigStringErrorsGiveMeaningfulMessages(string configString, string expected, string paramName)
{
- var ex = Assert.Throws(() => ConfigurationOptions.Parse(configString));
+ var ex = Assert.Throws(() => Parse(configString));
Assert.StartsWith(expected, ex.Message); // param name gets concatenated sometimes
Assert.Equal(paramName, ex.ParamName); // param name gets concatenated sometimes
}
@@ -619,7 +649,7 @@ public void ConfigStringErrorsGiveMeaningfulMessages(string configString, string
[Fact]
public void ConfigStringInvalidOptionErrorGiveMeaningfulMessages()
{
- var ex = Assert.Throws(() => ConfigurationOptions.Parse("foo,flibble=value"));
+ var ex = Assert.Throws(() => Parse("foo,flibble=value"));
Assert.StartsWith("Keyword 'flibble' is not supported.", ex.Message); // param name gets concatenated sometimes
Assert.Equal("flibble", ex.ParamName);
}
@@ -627,7 +657,7 @@ public void ConfigStringInvalidOptionErrorGiveMeaningfulMessages()
[Fact]
public void NullApply()
{
- var options = ConfigurationOptions.Parse("127.0.0.1,name=FooApply");
+ var options = Parse("127.0.0.1,name=FooApply");
Assert.Equal("FooApply", options.ClientName);
// Doesn't go boom
@@ -639,7 +669,7 @@ public void NullApply()
[Fact]
public void Apply()
{
- var options = ConfigurationOptions.Parse("127.0.0.1,name=FooApply");
+ var options = Parse("127.0.0.1,name=FooApply");
Assert.Equal("FooApply", options.ClientName);
var randomName = Guid.NewGuid().ToString();
@@ -653,7 +683,7 @@ public void Apply()
[Fact]
public async Task BeforeSocketConnect()
{
- var options = ConfigurationOptions.Parse(TestConfig.Current.PrimaryServerAndPort);
+ var options = Parse(TestConfig.Current.PrimaryServerAndPort);
int count = 0;
options.BeforeSocketConnect = (endpoint, connType, socket) =>
{
@@ -664,7 +694,7 @@ public async Task BeforeSocketConnect()
};
await using var conn = ConnectionMultiplexer.Connect(options);
Assert.True(conn.IsConnected);
- Assert.Equal(2, count);
+ Assert.Equal(options.TryResp3() ? 1 : 2, count);
var endpoint = conn.GetServerSnapshot()[0];
var interactivePhysical = endpoint.GetBridge(ConnectionType.Interactive)?.TryConnect(null);
@@ -678,7 +708,10 @@ public async Task BeforeSocketConnect()
Assert.NotNull(subscriptionSocket);
Assert.Equal(12, interactiveSocket.Ttl);
- Assert.Equal(123, subscriptionSocket.Ttl);
+ if (!ReferenceEquals(interactiveSocket, subscriptionSocket))
+ {
+ Assert.Equal(123, subscriptionSocket.Ttl);
+ }
Assert.True(interactiveSocket.DontFragment);
Assert.True(subscriptionSocket.DontFragment);
}
@@ -686,13 +719,17 @@ public async Task BeforeSocketConnect()
[Fact]
public async Task MutableOptions()
{
- var options = ConfigurationOptions.Parse(TestConfig.Current.PrimaryServerAndPort + ",name=Details");
+ var options = Parse(TestConfig.Current.PrimaryServerAndPort + ",name=Details");
options.LoggerFactory = NullLoggerFactory.Instance;
var originalConfigChannel = options.ConfigurationChannel = "originalConfig";
var originalUser = options.User = "originalUser";
var originalPassword = options.Password = "originalPassword";
Assert.Equal("Details", options.ClientName);
- await using var conn = await ConnectionMultiplexer.ConnectAsync(options);
+ Assert.SkipWhen(options.TryResp3(), "only validate RESP2");
+ Log(options.ToString());
+ await using var conn = await ConnectionMultiplexer.ConnectAsync(options, log: Writer);
+ Assert.NotNull(conn.AuthException);
+ Log($"auth failure: {conn.AuthException.Message}");
// Same instance
Assert.Same(options, conn.RawConfig);
@@ -737,6 +774,7 @@ public async Task MutableOptions()
var newPass = options.Password = "newPassword";
Assert.Equal(newPass, conn.RawConfig.Password);
Assert.Equal(options.LoggerFactory, conn.RawConfig.LoggerFactory);
+ Log("complete");
}
[Theory]
@@ -744,7 +782,7 @@ public async Task MutableOptions()
[InlineData("http:somewhere:22", "http:somewhere:22")]
public void HttpTunnelCanRoundtrip(string input, string expected)
{
- var config = ConfigurationOptions.Parse($"127.0.0.1:6380,tunnel={input}");
+ var config = Parse($"127.0.0.1:6380,tunnel={input}");
var ip = Assert.IsType(Assert.Single(config.EndPoints));
Assert.Equal(6380, ip.Port);
Assert.Equal("127.0.0.1", ip.Address.ToString());
@@ -753,7 +791,7 @@ public void HttpTunnelCanRoundtrip(string input, string expected)
Assert.Equal(expected, config.Tunnel.ToString());
var cs = config.ToString();
- Assert.Equal($"127.0.0.1:6380,tunnel={expected}", cs);
+ Assert.Equal($"127.0.0.1:6380,tunnel={expected}", RemoveTestDefaults(cs));
}
private sealed class CustomTunnel : Tunnel { }
@@ -763,11 +801,11 @@ public void CustomTunnelCanRoundtripMinusTunnel()
{
// we don't expect to be able to parse custom tunnels, but we should still be able to round-trip
// the rest of the config, which means ignoring them *in both directions* (unless first party)
- var options = ConfigurationOptions.Parse("127.0.0.1,Ssl=true");
+ var options = Parse("127.0.0.1,Ssl=true");
options.Tunnel = new CustomTunnel();
var cs = options.ToString();
- Assert.Equal("127.0.0.1,ssl=True", cs);
- options = ConfigurationOptions.Parse(cs);
+ Assert.Equal("127.0.0.1,ssl=True", RemoveTestDefaults(cs));
+ options = Parse(cs);
Assert.Null(options.Tunnel);
}
@@ -777,12 +815,12 @@ public void CustomTunnelCanRoundtripMinusTunnel()
[InlineData("server:6379,setlib=False", false)]
public void DefaultConfigOptionsForSetLib(string configurationString, bool setlib)
{
- var options = ConfigurationOptions.Parse(configurationString);
+ var options = Parse(configurationString);
Assert.Equal(setlib, options.SetClientLibrary);
- Assert.Equal(configurationString, options.ToString());
+ Assert.Equal(configurationString, RemoveTestDefaults(options.ToString()));
options = options.Clone();
Assert.Equal(setlib, options.SetClientLibrary);
- Assert.Equal(configurationString, options.ToString());
+ Assert.Equal(configurationString, RemoveTestDefaults(options.ToString()));
}
[Theory]
@@ -791,17 +829,17 @@ public void DefaultConfigOptionsForSetLib(string configurationString, bool setli
[InlineData(true, true, "dummy,highIntegrity=True")]
public void CheckHighIntegrity(bool? assigned, bool expected, string cs)
{
- var options = ConfigurationOptions.Parse("dummy");
+ var options = Parse("dummy");
if (assigned.HasValue) options.HighIntegrity = assigned.Value;
Assert.Equal(expected, options.HighIntegrity);
- Assert.Equal(cs, options.ToString());
+ Assert.Equal(cs, RemoveTestDefaults(options.ToString()));
var clone = options.Clone();
Assert.Equal(expected, clone.HighIntegrity);
- Assert.Equal(cs, clone.ToString());
+ Assert.Equal(cs, RemoveTestDefaults(clone.ToString()));
- var parsed = ConfigurationOptions.Parse(cs);
+ var parsed = Parse(cs);
Assert.Equal(expected, parsed.HighIntegrity);
}
diff --git a/tests/StackExchange.Redis.Tests/Helpers/Attributes.cs b/tests/StackExchange.Redis.Tests/Helpers/Attributes.cs
index a3386e80c..1f29a6b55 100644
--- a/tests/StackExchange.Redis.Tests/Helpers/Attributes.cs
+++ b/tests/StackExchange.Redis.Tests/Helpers/Attributes.cs
@@ -59,7 +59,7 @@ protected override ValueTask> CreateTestCase
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
-public class RunPerProtocol() : Attribute { }
+public class RunPerProtocolAttribute() : Attribute { }
public interface IProtocolTestCase
{
@@ -155,8 +155,8 @@ public static async ValueTask> ExpandAsync(t
{
var testMethod = testCase.TestMethod;
- if ((testMethod.Method.GetCustomAttributes(typeof(RunPerProtocol)).FirstOrDefault()
- ?? testMethod.TestClass.Class.GetCustomAttributes(typeof(RunPerProtocol)).FirstOrDefault()) is RunPerProtocol)
+ if ((testMethod.Method.GetCustomAttributes(typeof(RunPerProtocolAttribute)).FirstOrDefault()
+ ?? testMethod.TestClass.Class.GetCustomAttributes(typeof(RunPerProtocolAttribute)).FirstOrDefault()) is RunPerProtocolAttribute)
{
result.Add(CreateTestCase(testCase, RedisProtocol.Resp2));
result.Add(CreateTestCase(testCase, RedisProtocol.Resp3));
diff --git a/tests/StackExchange.Redis.Tests/RespProtocolTests.cs b/tests/StackExchange.Redis.Tests/RespProtocolTests.cs
index 3e469918e..69bd26dbd 100644
--- a/tests/StackExchange.Redis.Tests/RespProtocolTests.cs
+++ b/tests/StackExchange.Redis.Tests/RespProtocolTests.cs
@@ -18,7 +18,7 @@ public async Task ConnectWithTiming()
[Theory]
// specify nothing
- [InlineData("someserver", false)]
+ [InlineData("someserver", true)]
// specify *just* the protocol; sure, we'll believe you
[InlineData("someserver,protocol=resp3", true)]
[InlineData("someserver,protocol=resp3,$HELLO=", false)]
@@ -43,9 +43,9 @@ public async Task ConnectWithTiming()
[InlineData("someserver,version=5.9,protocol=2,$HELLO=", false, "resp2")]
[InlineData("someserver,version=5.9,protocol=2,$HELLO=BONJOUR", false, "resp2")]
// specify a post-6 version; attempt by default
- [InlineData("someserver,version=6.0", false)]
+ [InlineData("someserver,version=6.0", true)]
[InlineData("someserver,version=6.0,$HELLO=", false)]
- [InlineData("someserver,version=6.0,$HELLO=BONJOUR", false)]
+ [InlineData("someserver,version=6.0,$HELLO=BONJOUR", true)]
[InlineData("someserver,version=6.0,protocol=resp3", true)]
[InlineData("someserver,version=6.0,protocol=resp3,$HELLO=", false)]
[InlineData("someserver,version=6.0,protocol=resp3,$HELLO=BONJOUR", true)]
@@ -55,9 +55,9 @@ public async Task ConnectWithTiming()
[InlineData("someserver,version=6.0,protocol=2", false, "resp2")]
[InlineData("someserver,version=6.0,protocol=2,$HELLO=", false, "resp2")]
[InlineData("someserver,version=6.0,protocol=2,$HELLO=BONJOUR", false, "resp2")]
- [InlineData("someserver,version=7.2", false)]
+ [InlineData("someserver,version=7.2", true)]
[InlineData("someserver,version=7.2,$HELLO=", false)]
- [InlineData("someserver,version=7.2,$HELLO=BONJOUR", false)]
+ [InlineData("someserver,version=7.2,$HELLO=BONJOUR", true)]
public void ParseFormatConfigOptions(string configurationString, bool tryResp3, string? formatProtocol = null)
{
var config = ConfigurationOptions.Parse(configurationString);