From 5c505a1955f2e2966f58bad32011348b2d9de143 Mon Sep 17 00:00:00 2001 From: Aris Rellegue Date: Thu, 8 Jun 2023 10:43:57 -0700 Subject: [PATCH 01/12] Add SqlConnectionEncryptOptionConverter class which is used to convert string Encrypt option into SqlConnectionEncryptionOption type. --- .../SqlConnectionEncryptOptionConverter.xml | 51 ++++++++++ src/Microsoft.Data.SqlClient.sln | 1 + .../src/Microsoft.Data.SqlClient.csproj | 3 + .../netfx/src/Microsoft.Data.SqlClient.csproj | 3 + .../SqlClient/SqlConnectionEncryptOption.cs | 2 + .../SqlConnectionEncryptOptionConverter.cs | 46 +++++++++ .../Microsoft.Data.SqlClient.Tests.csproj | 1 + .../SqlConnectionStringBuilderTest.cs | 93 +++++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml new file mode 100644 index 0000000000..9f26bc71c7 --- /dev/null +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml @@ -0,0 +1,51 @@ + + + + + Converts a string Sql Connection Encrypt option into SqlConnectionEncryptOption object + + + ## Remarks +Implicit conversions have been added to maintain backwards compatibility with boolean behahavior for the property. When converting from a boolean, a value of `true` converts to and a value of `false` converts to . When converting to a boolean, , , and `null` convert to `true` and converts `false`. + + + + + + If the source type is a string then conversion is allowed . + + A string containing the value to convert. + + if the parameter can be converted successfully; otherwise, . + + This method does not throw an exception. + + + + Converts the specified string representation of a logical value to its equivalent. + + A string containing the value to convert. + + An object that is equivalent to . + + + An object that is equivalent to with value of if conversion was successful; + otherwise, an exception is thrown. + + This method throws an exception if conversion fails. + + + + Converts an object value to its string representation. + + An object containing the value to convert. + + A string representation of the value of . + + + A string representation of the value of . + + This method does not throw an exception if conversion fails. + + + diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index c5b34945a0..a94447bf12 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -121,6 +121,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOptionConverter.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOptionConverter.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index be1eb19b17..41f8374191 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -330,6 +330,9 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs + + Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs + Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 4492274116..675dd57fe6 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -422,6 +422,9 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs + + Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs + Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs index ecabdb9f04..997833437f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs @@ -3,11 +3,13 @@ // See the LICENSE file in the project root for more information. using System; +using System.ComponentModel; using Microsoft.Data.Common; namespace Microsoft.Data.SqlClient { /// + [TypeConverter(typeof(SqlConnectionEncryptOptionConverter))] public sealed class SqlConnectionEncryptOption { private const string TRUE = "True"; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs new file mode 100644 index 0000000000..da5eb6f8a1 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Drawing; + +namespace Microsoft.Data.SqlClient +{ + /// + public class SqlConnectionEncryptOptionConverter : TypeConverter + { + // Overrides the CanConvertFrom method of TypeConverter. + // The ITypeDescriptorContext interface provides the context for the + // conversion. Typically, this interface is used at design time to + // provide information about the design-time container. + /// + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == typeof(string)) + { + return true; + } + return base.CanConvertFrom(context, sourceType); + } + // Overrides the ConvertFrom method of TypeConverter. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string) + { + return SqlConnectionEncryptOption.Parse(value.ToString()); + } + throw new Exception("Value to convert must be of string type!"); + } + // Overrides the ConvertTo method of TypeConverter. + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 9d1e8d5087..408d7ffa61 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -66,6 +66,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index 2bc842566a..591a426568 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -4,6 +4,12 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Text; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -468,6 +474,36 @@ public void EncryptTryParseInvalidValuesReturnsFalse(string value) Assert.Null(result); } + [Theory] + [InlineData("false","False")] + [InlineData("true", "True")] + [InlineData("strict", "Strict")] + [InlineData("mandatory","True")] + [InlineData("optional", "False")] + [InlineData("yes", "True")] + [InlineData("no", "False")] + [InlineData("absolutely", "True")] + [InlineData("affirmative", "True")] + [InlineData("never", "True")] + [InlineData("always", "True")] + [InlineData("none", "True")] + public void ConnectionStringFromJsonTests(string value, string expectedValue) + { + ExecuteConnectionStringFromJsonTests(value, expectedValue); + } + + [Theory] + [InlineData("absolutely")] + [InlineData("affirmative")] + [InlineData("never")] + [InlineData("always")] + [InlineData("none")] + [InlineData(" for sure ")] + public void ConnectionStringFromJsonThrowsException(string value) + { + ExecuteConnectionStringFromJsonThrowsException(value); + } + internal void ExecuteConnectionStringTests(string connectionString) { SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); @@ -495,5 +531,62 @@ internal static void CheckEncryptType(SqlConnectionStringBuilder builder, SqlCon Assert.IsType(builder.Encrypt); Assert.Equal(expectedValue, builder.Encrypt); } + + internal void ExecuteConnectionStringFromJsonTests(string encryptOption, string result) + { + var settings = LoadSettingsFromJsonStream(encryptOption); + var connectionString = settings!.UserDb!.ToString(); + Assert.Contains($"Encrypt={result}", connectionString, StringComparison.InvariantCultureIgnoreCase); + } + + internal void ExecuteConnectionStringFromJsonThrowsException(string encryptOption) + { + Assert.Throws(() => LoadSettingsFromJsonStream(encryptOption)); + } + + TSettings LoadSettingsFromJsonStream(string encryptOption) where TSettings : class + { + TSettings settingsOut = null; + + Host.CreateDefaultBuilder() + .ConfigureAppConfiguration((ctx, configBuilder) => + { + // Note: Inside string interpolation, a { should be {{ and a } should be }} + // First, declare a stringified JSON + var json = $"{{ \"UserDb\": {{ \"UserComponents\": {{ \"NetworkLibrary\": \"DBMSSOCN\", \"UserID\": \"user\", \"Password\": \"password\", \"DataSource\": \"localhost\", \"InitialCatalog\": \"catalog\", \"Encrypt\": \"{encryptOption}\" }}}}}}"; + + // Load the stringified JSON as a stream into the configuration builder + configBuilder.AddJsonStream(new MemoryStream(Encoding.ASCII.GetBytes(json))); + configBuilder.AddEnvironmentVariables(); + }) + .ConfigureServices((ctx, services) => + { + var configuration = ctx.Configuration; + services.AddOptions(); + services.Configure(ctx.Configuration); + settingsOut = configuration.Get(); + }) + .Build(); + + return settingsOut; + } + } + + // These 2 classes will be used by ConnectionStringFromJsonTests only + internal class UserDbConnectionStringSettings + { + [Required] + public UserSqlConnectionString UserDb { get; set; } + } + + internal class UserSqlConnectionString + { + public SqlConnectionStringBuilder UserComponents { get; set; } = new(); + + public override string ToString() + { + return UserComponents!.ConnectionString; + } } + } From 7f09dd92bb5172c28c0a3ea030059ad3e68b08b9 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Thu, 15 Jun 2023 15:09:07 -0700 Subject: [PATCH 02/12] Add StringComparison.OrdinalIgnoreCase in InferNamedPipesInformation in SNIProxy. --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index ac4d3599dd..56d4fbb838 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -675,7 +675,7 @@ private void ReportSNIError(SNIProviders provider) private bool InferNamedPipesInformation() { // If we have a datasource beginning with a pipe or we have already determined that the protocol is Named Pipe - if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning) || _connectionProtocol == Protocol.NP) + if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning, StringComparison.OrdinalIgnoreCase) || _connectionProtocol == Protocol.NP) { // If the data source is "np:servername" if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning)) @@ -714,7 +714,7 @@ private bool InferNamedPipesInformation() return false; } - if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader)) + if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader, StringComparison.OrdinalIgnoreCase)) { InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length); } From 713b2157076ba7c0d7bafef1c971dcf123ecd986 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 16 Jun 2023 09:13:49 -0700 Subject: [PATCH 03/12] Added unit test using th-TH culture info. --- .../SqlConnectionBasicTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 916cbf83b4..3ac53f4149 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -5,8 +5,10 @@ using System; using System.Data; using System.Data.Common; +using System.Globalization; using System.Reflection; using System.Security; +using System.Threading; using System.Threading.Tasks; using Microsoft.SqlServer.TDS.Servers; using Xunit; @@ -23,6 +25,27 @@ public void ConnectionTest() connection.Open(); } + [Fact] + public void ConnectionTestWithCultureTH() + { + // Save current cultures + CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; + CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture; + + Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); + + using TestTdsServer server = TestTdsServer.StartTestServer(); + using SqlConnection connection = new SqlConnection(server.ConnectionString); + connection.Open(); + + // Restore saved cultures + Thread.CurrentThread.CurrentCulture = currentCulture; + Thread.CurrentThread.CurrentUICulture = currentUICulture; + + Assert.Equal(ConnectionState.Open, connection.State); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] [ActiveIssue(4830, TestPlatforms.AnyUnix)] [PlatformSpecific(TestPlatforms.Windows)] From 1bc7d7dfd9c75ca1f6fc65797cc9217c2da804f4 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 16 Jun 2023 11:54:22 -0700 Subject: [PATCH 04/12] Revert "Add SqlConnectionEncryptOptionConverter class which is used to convert string Encrypt option into SqlConnectionEncryptionOption type." This reverts commit 5c505a1955f2e2966f58bad32011348b2d9de143. --- .../SqlConnectionEncryptOptionConverter.xml | 51 ---------- src/Microsoft.Data.SqlClient.sln | 1 - .../src/Microsoft.Data.SqlClient.csproj | 3 - .../netfx/src/Microsoft.Data.SqlClient.csproj | 3 - .../SqlClient/SqlConnectionEncryptOption.cs | 2 - .../SqlConnectionEncryptOptionConverter.cs | 46 --------- .../Microsoft.Data.SqlClient.Tests.csproj | 1 - .../SqlConnectionStringBuilderTest.cs | 93 ------------------- 8 files changed, 200 deletions(-) delete mode 100644 doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml deleted file mode 100644 index 9f26bc71c7..0000000000 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOptionConverter.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Converts a string Sql Connection Encrypt option into SqlConnectionEncryptOption object - - - ## Remarks -Implicit conversions have been added to maintain backwards compatibility with boolean behahavior for the property. When converting from a boolean, a value of `true` converts to and a value of `false` converts to . When converting to a boolean, , , and `null` convert to `true` and converts `false`. - - - - - - If the source type is a string then conversion is allowed . - - A string containing the value to convert. - - if the parameter can be converted successfully; otherwise, . - - This method does not throw an exception. - - - - Converts the specified string representation of a logical value to its equivalent. - - A string containing the value to convert. - - An object that is equivalent to . - - - An object that is equivalent to with value of if conversion was successful; - otherwise, an exception is thrown. - - This method throws an exception if conversion fails. - - - - Converts an object value to its string representation. - - An object containing the value to convert. - - A string representation of the value of . - - - A string representation of the value of . - - This method does not throw an exception if conversion fails. - - - diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index a94447bf12..c5b34945a0 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -121,7 +121,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml - ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOptionConverter.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOptionConverter.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 90367cf55a..66791366f3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -330,9 +330,6 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs - - Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs - Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 675dd57fe6..4492274116 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -422,9 +422,6 @@ Microsoft\Data\SqlClient\SqlConnectionEncryptOption.cs - - Microsoft\Data\SqlClient\SqlConnectionEncryptOptionConverter.cs - Microsoft\Data\SqlClient\SqlConnectionPoolGroupProviderInfo.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs index 997833437f..ecabdb9f04 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOption.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using System.ComponentModel; using Microsoft.Data.Common; namespace Microsoft.Data.SqlClient { /// - [TypeConverter(typeof(SqlConnectionEncryptOptionConverter))] public sealed class SqlConnectionEncryptOption { private const string TRUE = "True"; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs deleted file mode 100644 index da5eb6f8a1..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionEncryptOptionConverter.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - -using System; -using System.ComponentModel; -using System.Globalization; -using System.Drawing; - -namespace Microsoft.Data.SqlClient -{ - /// - public class SqlConnectionEncryptOptionConverter : TypeConverter - { - // Overrides the CanConvertFrom method of TypeConverter. - // The ITypeDescriptorContext interface provides the context for the - // conversion. Typically, this interface is used at design time to - // provide information about the design-time container. - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - if (sourceType == typeof(string)) - { - return true; - } - return base.CanConvertFrom(context, sourceType); - } - // Overrides the ConvertFrom method of TypeConverter. - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value is string) - { - return SqlConnectionEncryptOption.Parse(value.ToString()); - } - throw new Exception("Value to convert must be of string type!"); - } - // Overrides the ConvertTo method of TypeConverter. - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - return base.ConvertTo(context, culture, value, destinationType); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 408d7ffa61..9d1e8d5087 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -66,7 +66,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index 591a426568..2bc842566a 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -4,12 +4,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.IO; -using System.Text; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -474,36 +468,6 @@ public void EncryptTryParseInvalidValuesReturnsFalse(string value) Assert.Null(result); } - [Theory] - [InlineData("false","False")] - [InlineData("true", "True")] - [InlineData("strict", "Strict")] - [InlineData("mandatory","True")] - [InlineData("optional", "False")] - [InlineData("yes", "True")] - [InlineData("no", "False")] - [InlineData("absolutely", "True")] - [InlineData("affirmative", "True")] - [InlineData("never", "True")] - [InlineData("always", "True")] - [InlineData("none", "True")] - public void ConnectionStringFromJsonTests(string value, string expectedValue) - { - ExecuteConnectionStringFromJsonTests(value, expectedValue); - } - - [Theory] - [InlineData("absolutely")] - [InlineData("affirmative")] - [InlineData("never")] - [InlineData("always")] - [InlineData("none")] - [InlineData(" for sure ")] - public void ConnectionStringFromJsonThrowsException(string value) - { - ExecuteConnectionStringFromJsonThrowsException(value); - } - internal void ExecuteConnectionStringTests(string connectionString) { SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); @@ -531,62 +495,5 @@ internal static void CheckEncryptType(SqlConnectionStringBuilder builder, SqlCon Assert.IsType(builder.Encrypt); Assert.Equal(expectedValue, builder.Encrypt); } - - internal void ExecuteConnectionStringFromJsonTests(string encryptOption, string result) - { - var settings = LoadSettingsFromJsonStream(encryptOption); - var connectionString = settings!.UserDb!.ToString(); - Assert.Contains($"Encrypt={result}", connectionString, StringComparison.InvariantCultureIgnoreCase); - } - - internal void ExecuteConnectionStringFromJsonThrowsException(string encryptOption) - { - Assert.Throws(() => LoadSettingsFromJsonStream(encryptOption)); - } - - TSettings LoadSettingsFromJsonStream(string encryptOption) where TSettings : class - { - TSettings settingsOut = null; - - Host.CreateDefaultBuilder() - .ConfigureAppConfiguration((ctx, configBuilder) => - { - // Note: Inside string interpolation, a { should be {{ and a } should be }} - // First, declare a stringified JSON - var json = $"{{ \"UserDb\": {{ \"UserComponents\": {{ \"NetworkLibrary\": \"DBMSSOCN\", \"UserID\": \"user\", \"Password\": \"password\", \"DataSource\": \"localhost\", \"InitialCatalog\": \"catalog\", \"Encrypt\": \"{encryptOption}\" }}}}}}"; - - // Load the stringified JSON as a stream into the configuration builder - configBuilder.AddJsonStream(new MemoryStream(Encoding.ASCII.GetBytes(json))); - configBuilder.AddEnvironmentVariables(); - }) - .ConfigureServices((ctx, services) => - { - var configuration = ctx.Configuration; - services.AddOptions(); - services.Configure(ctx.Configuration); - settingsOut = configuration.Get(); - }) - .Build(); - - return settingsOut; - } - } - - // These 2 classes will be used by ConnectionStringFromJsonTests only - internal class UserDbConnectionStringSettings - { - [Required] - public UserSqlConnectionString UserDb { get; set; } - } - - internal class UserSqlConnectionString - { - public SqlConnectionStringBuilder UserComponents { get; set; } = new(); - - public override string ToString() - { - return UserComponents!.ConnectionString; - } } - } From 89340b666af3dd3e7fa332c82b749f5fa76fef09 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 16 Jun 2023 12:49:26 -0700 Subject: [PATCH 05/12] Enclose in try catch finally the setting of th-TH culture in unit test. --- .../SqlConnectionBasicTests.cs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 3ac53f4149..b72273bd85 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -32,18 +32,27 @@ public void ConnectionTestWithCultureTH() CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); - - using TestTdsServer server = TestTdsServer.StartTestServer(); - using SqlConnection connection = new SqlConnection(server.ConnectionString); - connection.Open(); + try + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); - // Restore saved cultures - Thread.CurrentThread.CurrentCulture = currentCulture; - Thread.CurrentThread.CurrentUICulture = currentUICulture; + using TestTdsServer server = TestTdsServer.StartTestServer(); + using SqlConnection connection = new SqlConnection(server.ConnectionString); + connection.Open(); + Assert.Equal(ConnectionState.Open, connection.State); + } + catch (Exception e) + { + Assert.False(true, e.Message); + } + finally + { + // Restore saved cultures + Thread.CurrentThread.CurrentCulture = currentCulture; + Thread.CurrentThread.CurrentUICulture = currentUICulture; + } - Assert.Equal(ConnectionState.Open, connection.State); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] From d510fec7995cf53b605ed1b066a51bca02e8793e Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 16 Jun 2023 13:04:17 -0700 Subject: [PATCH 06/12] Raname currentCulture to saveCulture. --- .../tests/FunctionalTests/SqlConnectionBasicTests.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index b72273bd85..a2b04500ad 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -29,8 +29,8 @@ public void ConnectionTest() public void ConnectionTestWithCultureTH() { // Save current cultures - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture; + CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; + CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; try { @@ -49,10 +49,9 @@ public void ConnectionTestWithCultureTH() finally { // Restore saved cultures - Thread.CurrentThread.CurrentCulture = currentCulture; - Thread.CurrentThread.CurrentUICulture = currentUICulture; + if (Thread.CurrentThread.CurrentCulture != savedCulture) Thread.CurrentThread.CurrentCulture = savedCulture; + if (Thread.CurrentThread.CurrentUICulture != savedUICulture) Thread.CurrentThread.CurrentUICulture = savedUICulture; } - } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] From a67795c9f534767d33a2f2b81cce750a655ad3ca Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Mon, 19 Jun 2023 12:47:46 -0700 Subject: [PATCH 07/12] Changed StringComparison option from OrdinalIgnoreCase to Ordinal. --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 56d4fbb838..0e8f2feeca 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -675,7 +675,7 @@ private void ReportSNIError(SNIProviders provider) private bool InferNamedPipesInformation() { // If we have a datasource beginning with a pipe or we have already determined that the protocol is Named Pipe - if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning, StringComparison.OrdinalIgnoreCase) || _connectionProtocol == Protocol.NP) + if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning, StringComparison.Ordinal) || _connectionProtocol == Protocol.NP) { // If the data source is "np:servername" if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning)) @@ -714,7 +714,7 @@ private bool InferNamedPipesInformation() return false; } - if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader, StringComparison.OrdinalIgnoreCase)) + if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader, StringComparison.Ordinal)) { InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length); } From 69736aa47cff2a5b458215bed7e34cba0a2f185f Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Tue, 20 Jun 2023 16:01:32 -0700 Subject: [PATCH 08/12] Move the th-TH unit test to Manual test project. Add isUsingManagedSNI annotation to unit test. --- .../SqlConnectionBasicTests.cs | 29 ------------ ....Data.SqlClient.ManualTesting.Tests.csproj | 1 + .../CultureTest/CultureConnectivityTest.cs | 45 +++++++++++++++++++ 3 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index a2b04500ad..143dd4b263 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -25,35 +25,6 @@ public void ConnectionTest() connection.Open(); } - [Fact] - public void ConnectionTestWithCultureTH() - { - // Save current cultures - CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; - CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); - - using TestTdsServer server = TestTdsServer.StartTestServer(); - using SqlConnection connection = new SqlConnection(server.ConnectionString); - connection.Open(); - Assert.Equal(ConnectionState.Open, connection.State); - } - catch (Exception e) - { - Assert.False(true, e.Message); - } - finally - { - // Restore saved cultures - if (Thread.CurrentThread.CurrentCulture != savedCulture) Thread.CurrentThread.CurrentCulture = savedCulture; - if (Thread.CurrentThread.CurrentUICulture != savedUICulture) Thread.CurrentThread.CurrentUICulture = savedUICulture; - } - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] [ActiveIssue(4830, TestPlatforms.AnyUnix)] [PlatformSpecific(TestPlatforms.Windows)] diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 84d74244a5..981150005b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -275,6 +275,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs new file mode 100644 index 0000000000..2d167bc256 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; +using static Microsoft.Data.SqlClient.ManualTesting.Tests.DataTestUtility; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class CultureConnectivityTest + { + [ConditionalFact(typeof(DataTestUtility), nameof(IsUsingManagedSNI))] + public void ConnectionTestWithCultureTH() + { + AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true); + // Save current cultures + CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; + CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); + + using TestTdsServer server = TestTdsServer.StartTestServer(); + using SqlConnection connection = new SqlConnection(server.ConnectionString); + connection.Open(); + Assert.Equal(ConnectionState.Open, connection.State); + } + finally + { + // Restore saved cultures + if (Thread.CurrentThread.CurrentCulture != savedCulture) + Thread.CurrentThread.CurrentCulture = savedCulture; + if (Thread.CurrentThread.CurrentUICulture != savedUICulture) + Thread.CurrentThread.CurrentUICulture = savedUICulture; + } + } + + } +} From a45a47c7f9a0d805ec71f81b9197d62cc68ca376 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Tue, 20 Jun 2023 16:01:58 -0700 Subject: [PATCH 09/12] Removed blank line. --- .../ManualTests/SQL/CultureTest/CultureConnectivityTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs index 2d167bc256..65f7f87055 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs @@ -16,7 +16,7 @@ public class CultureConnectivityTest [ConditionalFact(typeof(DataTestUtility), nameof(IsUsingManagedSNI))] public void ConnectionTestWithCultureTH() { - AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true); + //AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true); // Used this only when testing locally // Save current cultures CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; @@ -40,6 +40,5 @@ public void ConnectionTestWithCultureTH() Thread.CurrentThread.CurrentUICulture = savedUICulture; } } - } } From 650cc6c562118c09f6f9d2507d6b8fd3addb30be Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Wed, 21 Jun 2023 11:20:07 -0700 Subject: [PATCH 10/12] Move ConnectionTestWithCutltureTH back to SqlConnectionBasicTests. Replaced [ConditionalFact] with just [Fact] Added catch { throw; } back. --- .../SqlConnectionBasicTests.cs | 31 +++++++++++++ ....Data.SqlClient.ManualTesting.Tests.csproj | 1 - .../CultureTest/CultureConnectivityTest.cs | 44 ------------------- 3 files changed, 31 insertions(+), 45 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 143dd4b263..3289070a0b 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -250,5 +250,36 @@ public void ConnectionTestValidCredentialCombination() Assert.Equal(sqlCredential, conn.Credential); } + + [Fact] + public void ConnectionTestWithCultureTH() + { + CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; + CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); + Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); + + using TestTdsServer server = TestTdsServer.StartTestServer(); + using SqlConnection connection = new SqlConnection(server.ConnectionString); + connection.Open(); + Assert.Equal(ConnectionState.Open, connection.State); + } + catch + { + throw; + } + finally + { + // Restore saved cultures + if (Thread.CurrentThread.CurrentCulture != savedCulture) + Thread.CurrentThread.CurrentCulture = savedCulture; + if (Thread.CurrentThread.CurrentUICulture != savedUICulture) + Thread.CurrentThread.CurrentUICulture = savedUICulture; + } + } + } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 981150005b..84d74244a5 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -275,7 +275,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs deleted file mode 100644 index 65f7f87055..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/CultureTest/CultureConnectivityTest.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Xunit; -using static Microsoft.Data.SqlClient.ManualTesting.Tests.DataTestUtility; - -namespace Microsoft.Data.SqlClient.ManualTesting.Tests -{ - public class CultureConnectivityTest - { - [ConditionalFact(typeof(DataTestUtility), nameof(IsUsingManagedSNI))] - public void ConnectionTestWithCultureTH() - { - //AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true); // Used this only when testing locally - // Save current cultures - CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; - CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentCulture = new CultureInfo("th-TH"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("th-TH"); - - using TestTdsServer server = TestTdsServer.StartTestServer(); - using SqlConnection connection = new SqlConnection(server.ConnectionString); - connection.Open(); - Assert.Equal(ConnectionState.Open, connection.State); - } - finally - { - // Restore saved cultures - if (Thread.CurrentThread.CurrentCulture != savedCulture) - Thread.CurrentThread.CurrentCulture = savedCulture; - if (Thread.CurrentThread.CurrentUICulture != savedUICulture) - Thread.CurrentThread.CurrentUICulture = savedUICulture; - } - } - } -} From 04953695e862b5ae95c3ff8fa7a2099202b5e46a Mon Sep 17 00:00:00 2001 From: Javad Date: Thu, 22 Jun 2023 18:44:02 -0700 Subject: [PATCH 11/12] Apply suggestions from code review --- .../tests/FunctionalTests/SqlConnectionBasicTests.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 3289070a0b..fab53dab54 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -267,10 +267,6 @@ public void ConnectionTestWithCultureTH() connection.Open(); Assert.Equal(ConnectionState.Open, connection.State); } - catch - { - throw; - } finally { // Restore saved cultures From 26c7eada8fad0bc2912d340f74c9b73e6c7b90a2 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Tue, 27 Jun 2023 14:03:35 -0700 Subject: [PATCH 12/12] Change comment to restore saved culture. --- .../tests/FunctionalTests/SqlConnectionBasicTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index fab53dab54..b973bae058 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -269,7 +269,7 @@ public void ConnectionTestWithCultureTH() } finally { - // Restore saved cultures + // Restore saved cultures if necessary if (Thread.CurrentThread.CurrentCulture != savedCulture) Thread.CurrentThread.CurrentCulture = savedCulture; if (Thread.CurrentThread.CurrentUICulture != savedUICulture)