From 8ddd3fc2fb5e0e51d53542bd6a5ac0e7bab7e26e Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Wed, 3 Apr 2024 11:39:42 -0700 Subject: [PATCH 01/14] Add fixes in SNIProxy to initialize InstanceName from data source. Added unit test to test GetSqlServerSPNs function to return port number for TCP and instance name for NP. --- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 25 ++++++++- .../SQL/InstanceNameTest/InstanceNameTest.cs | 51 ++++++++++++++----- src/NuGet.config | 2 + 3 files changed, 64 insertions(+), 14 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 3df369a2f6..36e4f7d80e 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 @@ -189,7 +189,7 @@ internal static SNIHandle CreateConnectionHandle( case DataSource.Protocol.TCP: sniHandle = CreateTcpHandle(details, timeout, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo, tlsFirst, hostNameInCertificate, serverCertificateFilename); - break; + break; case DataSource.Protocol.NP: sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); break; @@ -652,6 +652,11 @@ private bool InferConnectionDetails() } Port = port; + + if (InstanceName == null && backSlashIndex > -1 && tokensByCommaAndSlash.Length == 3) + { + InstanceName = tokensByCommaAndSlash[1].Trim(); + } } // Instance Name Handling. Only if we found a '\' and we did not find a port in the Data Source else if (backSlashIndex > -1) @@ -694,7 +699,7 @@ private bool InferNamedPipesInformation() if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning)) { // Assuming that user did not change default NamedPipe name, if the datasource is in the format servername\instance, - // separate servername and instance and prepend instance with MSSQL$ and append default pipe path + // separate server name and instance and prepend instance with MSSQL$ and append default pipe path // https://learn.microsoft.com/en-us/sql/tools/configuration-manager/named-pipes-properties?view=sql-server-ver16 if (_dataSourceAfterTrimmingProtocol.Contains(PathSeparator) && _connectionProtocol == Protocol.NP) { @@ -719,6 +724,10 @@ private bool InferNamedPipesInformation() } InferLocalServerName(); + + if (InstanceName == null) + InstanceName = GetInstanceNameFromDataSource(); + return true; } @@ -800,5 +809,17 @@ private bool InferNamedPipesInformation() private static bool IsLocalHost(string serverName) => ".".Equals(serverName) || "(local)".Equals(serverName) || "localhost".Equals(serverName); + + private string GetInstanceNameFromDataSource() + { + string instanceName = ""; + string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter); + if (tokensByBackSlash.Length > 1) + { + instanceName = tokensByBackSlash[1]; + } + + return instanceName; + } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index aa72bb6f5b..1e3ea198c5 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Data.Common; using System.Net; using System.Net.Sockets; using System.Reflection; @@ -87,9 +88,8 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove } #if NETCOREAPP - [ActiveIssue("27824")] // When specifying instance name and port number, this method call always returns false [ConditionalFact(nameof(IsSPNPortNumberTestForTCP))] - public static void PortNumberInSPNTestForTCP() + public static void SPNTestForTCPMustReturnPortNumber() { string connectionString = DataTestUtility.TCPConnectionString; SqlConnectionStringBuilder builder = new(connectionString); @@ -98,11 +98,24 @@ public static void PortNumberInSPNTestForTCP() Assert.True(port > 0, "Named instance must have a valid port number."); builder.DataSource = $"{builder.DataSource},{port}"; - PortNumberInSPNTest(builder.ConnectionString, port); + PortNumberInSPNTest(connectionString: builder.ConnectionString, expectedPortNumber: port); + } + + [ConditionalFact(nameof(IsSPNPortNumberTestForNP))] + public static void SPNTestForNPMustReturnNamedInstance() + { + string connectionString = DataTestUtility.NPConnectionString; + SqlConnectionStringBuilder builder = new(connectionString); + + string instanceName = ""; + DataTestUtility.ParseDataSource(builder.DataSource, out _, out _, out instanceName); + + Assert.True(!string.IsNullOrEmpty(instanceName), "Instance name must be included in data source."); + PortNumberInSPNTest(connectionString: builder.ConnectionString, expectedInstanceName: instanceName.ToUpper()); } #endif - private static void PortNumberInSPNTest(string connectionString, int expectedPortNumber) + private static void PortNumberInSPNTest(string connectionString, int expectedPortNumber = 0, string expectedInstanceName = null) { if (DataTestUtility.IsIntegratedSecuritySetup()) { @@ -125,15 +138,22 @@ private static void PortNumberInSPNTest(string connectionString, int expectedPor connection.Open(); string spnInfo = GetSPNInfo(builder.DataSource); - Assert.Matches(@"MSSQLSvc\/.*:[\d]", spnInfo); - - string[] spnStrs = spnInfo.Split(':'); - int portInSPN = 0; - if (spnStrs.Length > 1) + if (expectedPortNumber > 0) { - int.TryParse(spnStrs[1], out portInSPN); + Assert.Matches(@"MSSQLSvc\/.*:[\d]", spnInfo); + string[] spnStrs = spnInfo.Split(':'); + int portInSPN = 0; + if (spnStrs.Length > 1) + { + int.TryParse(spnStrs[1], out portInSPN); + } + Assert.Equal(expectedPortNumber, portInSPN); + } + else + { + string[] spnStrs = spnInfo.Split(':'); + Assert.Equal(expectedInstanceName, spnStrs[1].ToUpper()); } - Assert.Equal(expectedPortNumber, portInSPN); } } @@ -180,7 +200,7 @@ private static string GetSPNInfo(string dataSource) string serverName = serverInfo.GetValue(dataSrcInfo, null).ToString(); PropertyInfo instanceNameInfo = dataSrcInfo.GetType().GetProperty("InstanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - string instanceName = instanceNameInfo.GetValue(dataSrcInfo, null).ToString(); + string instanceName = instanceNameInfo.GetValue(dataSrcInfo, null).ToString().ToUpper(); object port = getPortByInstanceNameInfo.Invoke(ssrpObj, parameters: new object[] { serverName, instanceName, timeoutTimerObj, false, 0 }); @@ -205,6 +225,13 @@ private static bool IsSPNPortNumberTestForTCP() && DataTestUtility.IsNotAzureSynapse()); } + private static bool IsSPNPortNumberTestForNP() + { + return (IsInstanceNameValid(DataTestUtility.NPConnectionString) + && DataTestUtility.IsUsingManagedSNI() + && DataTestUtility.IsNotAzureServer() + && DataTestUtility.IsNotAzureSynapse()); + } private static bool IsInstanceNameValid(string connectionString) { string instanceName = ""; diff --git a/src/NuGet.config b/src/NuGet.config index 3233e60161..a1bb4d4085 100644 --- a/src/NuGet.config +++ b/src/NuGet.config @@ -3,5 +3,7 @@ + + From f6f5d2eb71064a8792dc11b4ab3923894f4ad33d Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Wed, 3 Apr 2024 11:47:54 -0700 Subject: [PATCH 02/14] Revert changes to Nuget.config. --- src/NuGet.config | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/NuGet.config b/src/NuGet.config index a1bb4d4085..3233e60161 100644 --- a/src/NuGet.config +++ b/src/NuGet.config @@ -3,7 +3,5 @@ - - From 3681b82d9b42fb9c48d34a1f0f94a0090a41e310 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Wed, 3 Apr 2024 12:41:35 -0700 Subject: [PATCH 03/14] Applied suggestions in PR review. --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 2 +- .../tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs | 3 +-- 2 files changed, 2 insertions(+), 3 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 36e4f7d80e..25a15fc047 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 @@ -812,7 +812,7 @@ private static bool IsLocalHost(string serverName) private string GetInstanceNameFromDataSource() { - string instanceName = ""; + string instanceName = string.Empty; string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter); if (tokensByBackSlash.Length > 1) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index 1e3ea198c5..924e9e1ece 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -107,8 +107,7 @@ public static void SPNTestForNPMustReturnNamedInstance() string connectionString = DataTestUtility.NPConnectionString; SqlConnectionStringBuilder builder = new(connectionString); - string instanceName = ""; - DataTestUtility.ParseDataSource(builder.DataSource, out _, out _, out instanceName); + DataTestUtility.ParseDataSource(builder.DataSource, out _, out _, out string instanceName); Assert.True(!string.IsNullOrEmpty(instanceName), "Instance name must be included in data source."); PortNumberInSPNTest(connectionString: builder.ConnectionString, expectedInstanceName: instanceName.ToUpper()); From 940b4e7217751cd3a7c8628a0267b0ffcd528e91 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 12 Apr 2024 14:25:57 -0700 Subject: [PATCH 04/14] Added comment for usage of port and use Trim() for all usage of tokenByBackSlash string array. --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 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 25a15fc047..ff59404b29 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 @@ -651,6 +651,7 @@ private bool InferConnectionDetails() return false; } + // If user is connecting to a managed instance with port, e.g. localhost\INSTANCENAME,1434 Port = port; if (InstanceName == null && backSlashIndex > -1 && tokensByCommaAndSlash.Length == 3) @@ -708,7 +709,7 @@ private bool InferNamedPipesInformation() { // NamedPipeClientStream object will create the network path using PipeHostName and PipeName // and can be seen in its _normalizedPipePath variable in the format \\servername\pipe\MSSQL$\sql\query - PipeHostName = ServerName = tokensByBackSlash[0]; + PipeHostName = ServerName = tokensByBackSlash[0].Trim(); PipeName = $"{InstancePrefix}{tokensByBackSlash[1]}{PathSeparator}{DefaultPipeName}"; } else @@ -744,7 +745,7 @@ private bool InferNamedPipesInformation() return false; } - string host = tokensByBackSlash[2]; + string host = tokensByBackSlash[2].Trim(); if (string.IsNullOrEmpty(host)) { @@ -761,7 +762,7 @@ private bool InferNamedPipesInformation() if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader, StringComparison.Ordinal)) { - InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length); + InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length).Trim(); } StringBuilder pipeNameBuilder = new StringBuilder(); @@ -816,7 +817,7 @@ private string GetInstanceNameFromDataSource() string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter); if (tokensByBackSlash.Length > 1) { - instanceName = tokensByBackSlash[1]; + instanceName = tokensByBackSlash[1].Trim(); } return instanceName; From 0f7c222e2dd22052d665292a6ea7e5d610e1d163 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 12 Apr 2024 15:09:04 -0700 Subject: [PATCH 05/14] Added DataSource Parser Test of the DataTestUtility class. --- ....Data.SqlClient.ManualTesting.Tests.csproj | 1 + .../DataSourceParserTest.cs | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs 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 676f8126c6..b37aeec73e 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 @@ -178,6 +178,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs new file mode 100644 index 0000000000..814623eb2e --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs @@ -0,0 +1,61 @@ +// 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.Data.Common; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Xunit; +namespace Microsoft.Data.SqlClient.ManualTesting.Tests.SQL.DataSourceParserTest +{ + public class DataSourceParserTest + { + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + [InlineData("localhost")] + [InlineData("tcp:localhost")] + [InlineData("np:localhost")] + public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSource) + { + DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out _); + Assert.Equal("localhost", hostname); + } + + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + [InlineData("localhost,1433")] + [InlineData("tcp:localhost,1433")] + [InlineData("np:localhost,1433")] + public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string dataSource) + { + DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out _); + Assert.Equal("localhost", hostname); + Assert.Equal(1433, port); + } + + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + [InlineData("localhost\\MSSQLSERVER02")] + [InlineData("tcp:localhost\\MSSQLSERVER02")] + [InlineData("np:localhost\\MSSQLSERVER02")] + public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string dataSource) + { + DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName ); + Assert.Equal("localhost", hostname); + Assert.Equal("MSSQLSERVER02", instanceName); + } + + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] + [InlineData("localhost\\MSSQLSERVER02,1433")] + [InlineData("tcp:localhost\\MSSQLSERVER02,1433")] + [InlineData("np:localhost\\MSSQLSERVER02,1433")] + public void ParseDataSourceWithInstanceAndPortTestShouldSucceed(string dataSource) + { + DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out string instanceName); + Assert.Equal("localhost", hostname); + Assert.Equal("MSSQLSERVER02", instanceName); + Assert.Equal(1433, port); + } + } +} From a2f78d0b32f7079f2a86059f8373abecf9959d0e Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 12 Apr 2024 15:21:33 -0700 Subject: [PATCH 06/14] Added test cases of DataSource Parser with trailing, leading and embedded spaces. --- .../tests/ManualTests/DataCommon/DataTestUtility.cs | 5 +++++ .../SQL/DataSourceParserTest/DataSourceParserTest.cs | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index d588761bdb..3ebaa011aa 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -1004,6 +1004,11 @@ public static bool ParseDataSource(string dataSource, out string hostname, out i port = -1; instanceName = string.Empty; + // Remove leading and trailing spaces + dataSource = dataSource.Trim(); + // Remove all spaces + dataSource = dataSource.Replace(" ", string.Empty); + if (dataSource.Contains(":")) { dataSource = dataSource.Substring(dataSource.IndexOf(":", StringComparison.Ordinal) + 1); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs index 814623eb2e..e2019541e3 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs @@ -18,6 +18,9 @@ public class DataSourceParserTest [InlineData("localhost")] [InlineData("tcp:localhost")] [InlineData("np:localhost")] + [InlineData(" localhost ")] + [InlineData("tcp: localhost ")] + [InlineData("np: localhost" )] public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out _); @@ -28,6 +31,9 @@ public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSo [InlineData("localhost,1433")] [InlineData("tcp:localhost,1433")] [InlineData("np:localhost,1433")] + [InlineData("localhost , 1433 ")] + [InlineData("tcp:localhost , 1433 ")] + [InlineData("np:localhost , 1433 ")] public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out _); @@ -39,6 +45,9 @@ public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string da [InlineData("localhost\\MSSQLSERVER02")] [InlineData("tcp:localhost\\MSSQLSERVER02")] [InlineData("np:localhost\\MSSQLSERVER02")] + [InlineData("localhost \\ MSSQLSERVER02 ")] + [InlineData("tcp:localhost \\ MSSQLSERVER02 ")] + [InlineData("np:localhost \\ MSSQLSERVER02 ")] public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName ); @@ -50,6 +59,9 @@ public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string da [InlineData("localhost\\MSSQLSERVER02,1433")] [InlineData("tcp:localhost\\MSSQLSERVER02,1433")] [InlineData("np:localhost\\MSSQLSERVER02,1433")] + [InlineData("localhost \\ MSSQLSERVER02, 1433 ")] + [InlineData("tcp:localhost \\ MSSQLSERVER02, 1433 ")] + [InlineData("np:localhost \\ MSSQLSERVER02, 1433 ")] public void ParseDataSourceWithInstanceAndPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out string instanceName); From 76cd3502477c70e026fc94ae062b34e1f48a243e Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 26 Apr 2024 15:32:11 -0700 Subject: [PATCH 07/14] Reverted change to SNIProxy.cs so it no longer does force initialization of InstanceName property. Add IntanceName initialization using reflection instead in the unit test instead. --- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 20 ------------------- .../SQL/InstanceNameTest/InstanceNameTest.cs | 7 +++++-- 2 files changed, 5 insertions(+), 22 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 ff59404b29..27a6fad3ad 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 @@ -653,11 +653,6 @@ private bool InferConnectionDetails() // If user is connecting to a managed instance with port, e.g. localhost\INSTANCENAME,1434 Port = port; - - if (InstanceName == null && backSlashIndex > -1 && tokensByCommaAndSlash.Length == 3) - { - InstanceName = tokensByCommaAndSlash[1].Trim(); - } } // Instance Name Handling. Only if we found a '\' and we did not find a port in the Data Source else if (backSlashIndex > -1) @@ -726,9 +721,6 @@ private bool InferNamedPipesInformation() InferLocalServerName(); - if (InstanceName == null) - InstanceName = GetInstanceNameFromDataSource(); - return true; } @@ -810,17 +802,5 @@ private bool InferNamedPipesInformation() private static bool IsLocalHost(string serverName) => ".".Equals(serverName) || "(local)".Equals(serverName) || "localhost".Equals(serverName); - - private string GetInstanceNameFromDataSource() - { - string instanceName = string.Empty; - string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter); - if (tokensByBackSlash.Length > 1) - { - instanceName = tokensByBackSlash[1].Trim(); - } - - return instanceName; - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index 924e9e1ece..53f7f5d6d0 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -136,7 +136,7 @@ private static void PortNumberInSPNTest(string connectionString, int expectedPor { connection.Open(); - string spnInfo = GetSPNInfo(builder.DataSource); + string spnInfo = GetSPNInfo(builder.DataSource, instanceName); if (expectedPortNumber > 0) { Assert.Matches(@"MSSQLSvc\/.*:[\d]", spnInfo); @@ -156,7 +156,7 @@ private static void PortNumberInSPNTest(string connectionString, int expectedPor } } - private static string GetSPNInfo(string dataSource) + private static string GetSPNInfo(string dataSource, string inInstanceName) { Assembly sqlConnectionAssembly = Assembly.GetAssembly(typeof(SqlConnection)); @@ -198,6 +198,9 @@ private static string GetSPNInfo(string dataSource) PropertyInfo serverInfo = dataSrcInfo.GetType().GetProperty("ServerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string serverName = serverInfo.GetValue(dataSrcInfo, null).ToString(); + PropertyInfo instanceNameToSetInfo = dataSrcInfo.GetType().GetProperty("InstanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + instanceNameToSetInfo.SetValue(dataSrcInfo, inInstanceName, null); + PropertyInfo instanceNameInfo = dataSrcInfo.GetType().GetProperty("InstanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string instanceName = instanceNameInfo.GetValue(dataSrcInfo, null).ToString().ToUpper(); From b2ef4c50d06945deca47f94f117057932844eb6e Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Mon, 6 May 2024 09:56:41 -0700 Subject: [PATCH 08/14] Remove unused usings. --- .../SQL/DataSourceParserTest/DataSourceParserTest.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs index e2019541e3..9afa4963d4 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs @@ -2,14 +2,8 @@ // 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.Data.Common; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; using Xunit; + namespace Microsoft.Data.SqlClient.ManualTesting.Tests.SQL.DataSourceParserTest { public class DataSourceParserTest @@ -20,7 +14,7 @@ public class DataSourceParserTest [InlineData("np:localhost")] [InlineData(" localhost ")] [InlineData("tcp: localhost ")] - [InlineData("np: localhost" )] + [InlineData("np: localhost")] public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out _); @@ -50,7 +44,7 @@ public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string da [InlineData("np:localhost \\ MSSQLSERVER02 ")] public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string dataSource) { - DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName ); + DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName); Assert.Equal("localhost", hostname); Assert.Equal("MSSQLSERVER02", instanceName); } From 57ea9e6a413fa0386aa8cabd3f9385604696876a Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 10 May 2024 13:21:22 -0700 Subject: [PATCH 09/14] Revert all changes in SNIProxy.cs. --- .../src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 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 27a6fad3ad..2a22e7fba0 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 @@ -189,7 +189,7 @@ internal static SNIHandle CreateConnectionHandle( case DataSource.Protocol.TCP: sniHandle = CreateTcpHandle(details, timeout, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo, tlsFirst, hostNameInCertificate, serverCertificateFilename); - break; + break; case DataSource.Protocol.NP: sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); break; @@ -651,7 +651,6 @@ private bool InferConnectionDetails() return false; } - // If user is connecting to a managed instance with port, e.g. localhost\INSTANCENAME,1434 Port = port; } // Instance Name Handling. Only if we found a '\' and we did not find a port in the Data Source @@ -695,7 +694,7 @@ private bool InferNamedPipesInformation() if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning)) { // Assuming that user did not change default NamedPipe name, if the datasource is in the format servername\instance, - // separate server name and instance and prepend instance with MSSQL$ and append default pipe path + // separate servername and instance and prepend instance with MSSQL$ and append default pipe path // https://learn.microsoft.com/en-us/sql/tools/configuration-manager/named-pipes-properties?view=sql-server-ver16 if (_dataSourceAfterTrimmingProtocol.Contains(PathSeparator) && _connectionProtocol == Protocol.NP) { @@ -704,7 +703,7 @@ private bool InferNamedPipesInformation() { // NamedPipeClientStream object will create the network path using PipeHostName and PipeName // and can be seen in its _normalizedPipePath variable in the format \\servername\pipe\MSSQL$\sql\query - PipeHostName = ServerName = tokensByBackSlash[0].Trim(); + PipeHostName = ServerName = tokensByBackSlash[0]; PipeName = $"{InstancePrefix}{tokensByBackSlash[1]}{PathSeparator}{DefaultPipeName}"; } else @@ -737,7 +736,7 @@ private bool InferNamedPipesInformation() return false; } - string host = tokensByBackSlash[2].Trim(); + string host = tokensByBackSlash[2]; if (string.IsNullOrEmpty(host)) { @@ -754,7 +753,7 @@ private bool InferNamedPipesInformation() if (tokensByBackSlash[4].StartsWith(NamedPipeInstanceNameHeader, StringComparison.Ordinal)) { - InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length).Trim(); + InstanceName = tokensByBackSlash[4].Substring(NamedPipeInstanceNameHeader.Length); } StringBuilder pipeNameBuilder = new StringBuilder(); From 00a59611887ac2b820000b2a9e5185e7c0d04293 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 10 May 2024 13:23:17 -0700 Subject: [PATCH 10/14] Remove blank line at line 722 in SNIProxy.cs. --- .../netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 1 - 1 file changed, 1 deletion(-) 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 2a22e7fba0..3df369a2f6 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 @@ -719,7 +719,6 @@ private bool InferNamedPipesInformation() } InferLocalServerName(); - return true; } From 0086bfbad5894485d3f60cbf359125cf19cc52d9 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 10 May 2024 15:43:04 -0700 Subject: [PATCH 11/14] Add comment that the instance name is set in the SNI Proxy object from the unit test. --- .../ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index 53f7f5d6d0..e6e40a4aa3 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -197,10 +197,10 @@ private static string GetSPNInfo(string dataSource, string inInstanceName) PropertyInfo serverInfo = dataSrcInfo.GetType().GetProperty("ServerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string serverName = serverInfo.GetValue(dataSrcInfo, null).ToString(); - + // Set the instance name from the data source PropertyInfo instanceNameToSetInfo = dataSrcInfo.GetType().GetProperty("InstanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); instanceNameToSetInfo.SetValue(dataSrcInfo, inInstanceName, null); - + // Ensure that the instance name is set PropertyInfo instanceNameInfo = dataSrcInfo.GetType().GetProperty("InstanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string instanceName = instanceNameInfo.GetValue(dataSrcInfo, null).ToString().ToUpper(); From 291d3a7bca527fdbad3d06fb82f4a50d187913a7 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Fri, 24 May 2024 12:36:32 -0700 Subject: [PATCH 12/14] Changed pre-processor NETCOREAPP to NET6_0_OR_GREATER. --- .../tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index e6e40a4aa3..751cd0a35b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -87,7 +87,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove } } -#if NETCOREAPP +#if NET6_0_OR_GREATER [ConditionalFact(nameof(IsSPNPortNumberTestForTCP))] public static void SPNTestForTCPMustReturnPortNumber() { From 8a87c72a42d987e447c7c12d9f580b3577d42e94 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Tue, 18 Jun 2024 12:32:07 -0700 Subject: [PATCH 13/14] Applied suggested change. Remove inline data with embedded spaces. --- .../ManualTests/DataCommon/DataTestUtility.cs | 2 - .../DataSourceParserTest.cs | 46 ++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index b55753bebf..76bb715212 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -944,8 +944,6 @@ public static bool ParseDataSource(string dataSource, out string hostname, out i // Remove leading and trailing spaces dataSource = dataSource.Trim(); - // Remove all spaces - dataSource = dataSource.Replace(" ", string.Empty); if (dataSource.Contains(":")) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs index 9afa4963d4..6e4b59521f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs @@ -13,8 +13,14 @@ public class DataSourceParserTest [InlineData("tcp:localhost")] [InlineData("np:localhost")] [InlineData(" localhost ")] - [InlineData("tcp: localhost ")] - [InlineData("np: localhost")] + [InlineData(" tcp:localhost ")] + [InlineData(" np:localhost ")] + [InlineData(" localhost")] + [InlineData(" tcp:localhost")] + [InlineData(" np:localhost")] + [InlineData("localhost ")] + [InlineData("tcp:localhost ")] + [InlineData("np:localhost ")] public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out _); @@ -25,9 +31,15 @@ public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSo [InlineData("localhost,1433")] [InlineData("tcp:localhost,1433")] [InlineData("np:localhost,1433")] - [InlineData("localhost , 1433 ")] - [InlineData("tcp:localhost , 1433 ")] - [InlineData("np:localhost , 1433 ")] + [InlineData(" localhost,1433 ")] + [InlineData(" tcp:localhost,1433 ")] + [InlineData(" np:localhost,1433 ")] + [InlineData(" localhost,1433")] + [InlineData(" tcp:localhost,1433")] + [InlineData(" np:localhost,1433")] + [InlineData("localhost,1433 ")] + [InlineData("tcp:localhost,1433 ")] + [InlineData("np:localhost,1433 ")] public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out _); @@ -39,9 +51,15 @@ public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string da [InlineData("localhost\\MSSQLSERVER02")] [InlineData("tcp:localhost\\MSSQLSERVER02")] [InlineData("np:localhost\\MSSQLSERVER02")] - [InlineData("localhost \\ MSSQLSERVER02 ")] - [InlineData("tcp:localhost \\ MSSQLSERVER02 ")] - [InlineData("np:localhost \\ MSSQLSERVER02 ")] + [InlineData(" localhost\\MSSQLSERVER02 ")] + [InlineData(" tcp:localhost\\MSSQLSERVER02 ")] + [InlineData(" np:localhost\\MSSQLSERVER02 ")] + [InlineData(" localhost\\MSSQLSERVER02")] + [InlineData(" tcp:localhost\\MSSQLSERVER02")] + [InlineData(" np:localhost\\MSSQLSERVER02")] + [InlineData("localhost\\MSSQLSERVER02 ")] + [InlineData("tcp:localhost\\MSSQLSERVER02 ")] + [InlineData("np:localhost\\MSSQLSERVER02 ")] public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName); @@ -53,9 +71,15 @@ public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string da [InlineData("localhost\\MSSQLSERVER02,1433")] [InlineData("tcp:localhost\\MSSQLSERVER02,1433")] [InlineData("np:localhost\\MSSQLSERVER02,1433")] - [InlineData("localhost \\ MSSQLSERVER02, 1433 ")] - [InlineData("tcp:localhost \\ MSSQLSERVER02, 1433 ")] - [InlineData("np:localhost \\ MSSQLSERVER02, 1433 ")] + [InlineData(" localhost\\MSSQLSERVER02,1433 ")] + [InlineData(" tcp:localhost\\MSSQLSERVER02,1433 ")] + [InlineData(" np:localhost\\MSSQLSERVER02,1433 ")] + [InlineData(" localhost\\MSSQLSERVER02,1433")] + [InlineData(" tcp:localhost\\MSSQLSERVER02,1433")] + [InlineData(" np:localhost\\MSSQLSERVER02,1433")] + [InlineData("localhost\\MSSQLSERVER02,1433 ")] + [InlineData("tcp:localhost\\MSSQLSERVER02,1433 ")] + [InlineData("np:localhost\\MSSQLSERVER02,1433 ")] public void ParseDataSourceWithInstanceAndPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out string instanceName); From d04732132a24cfcb475ce506a638946ec01d20e4 Mon Sep 17 00:00:00 2001 From: v-arellegue Date: Wed, 28 Aug 2024 15:45:14 -0700 Subject: [PATCH 14/14] Removed test case for named pipe protocol as the parsing for tcp protocol should have identical behavior, it handles space and colon. --- .../DataSourceParserTest/DataSourceParserTest.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs index 6e4b59521f..38d4685537 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataSourceParserTest/DataSourceParserTest.cs @@ -11,16 +11,12 @@ public class DataSourceParserTest [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] [InlineData("localhost")] [InlineData("tcp:localhost")] - [InlineData("np:localhost")] [InlineData(" localhost ")] [InlineData(" tcp:localhost ")] - [InlineData(" np:localhost ")] [InlineData(" localhost")] [InlineData(" tcp:localhost")] - [InlineData(" np:localhost")] [InlineData("localhost ")] [InlineData("tcp:localhost ")] - [InlineData("np:localhost ")] public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out _); @@ -30,16 +26,12 @@ public void ParseDataSourceWithoutInstanceNorPortTestShouldSucceed(string dataSo [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] [InlineData("localhost,1433")] [InlineData("tcp:localhost,1433")] - [InlineData("np:localhost,1433")] [InlineData(" localhost,1433 ")] [InlineData(" tcp:localhost,1433 ")] - [InlineData(" np:localhost,1433 ")] [InlineData(" localhost,1433")] [InlineData(" tcp:localhost,1433")] - [InlineData(" np:localhost,1433")] [InlineData("localhost,1433 ")] [InlineData("tcp:localhost,1433 ")] - [InlineData("np:localhost,1433 ")] public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out _); @@ -50,16 +42,12 @@ public void ParseDataSourceWithoutInstanceButWithPortTestShouldSucceed(string da [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] [InlineData("localhost\\MSSQLSERVER02")] [InlineData("tcp:localhost\\MSSQLSERVER02")] - [InlineData("np:localhost\\MSSQLSERVER02")] [InlineData(" localhost\\MSSQLSERVER02 ")] [InlineData(" tcp:localhost\\MSSQLSERVER02 ")] - [InlineData(" np:localhost\\MSSQLSERVER02 ")] [InlineData(" localhost\\MSSQLSERVER02")] [InlineData(" tcp:localhost\\MSSQLSERVER02")] - [InlineData(" np:localhost\\MSSQLSERVER02")] [InlineData("localhost\\MSSQLSERVER02 ")] [InlineData("tcp:localhost\\MSSQLSERVER02 ")] - [InlineData("np:localhost\\MSSQLSERVER02 ")] public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out _, out string instanceName); @@ -70,16 +58,12 @@ public void ParseDataSourceWithInstanceButWithoutPortTestShouldSucceed(string da [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))] [InlineData("localhost\\MSSQLSERVER02,1433")] [InlineData("tcp:localhost\\MSSQLSERVER02,1433")] - [InlineData("np:localhost\\MSSQLSERVER02,1433")] [InlineData(" localhost\\MSSQLSERVER02,1433 ")] [InlineData(" tcp:localhost\\MSSQLSERVER02,1433 ")] - [InlineData(" np:localhost\\MSSQLSERVER02,1433 ")] [InlineData(" localhost\\MSSQLSERVER02,1433")] [InlineData(" tcp:localhost\\MSSQLSERVER02,1433")] - [InlineData(" np:localhost\\MSSQLSERVER02,1433")] [InlineData("localhost\\MSSQLSERVER02,1433 ")] [InlineData("tcp:localhost\\MSSQLSERVER02,1433 ")] - [InlineData("np:localhost\\MSSQLSERVER02,1433 ")] public void ParseDataSourceWithInstanceAndPortTestShouldSucceed(string dataSource) { DataTestUtility.ParseDataSource(dataSource, out string hostname, out int port, out string instanceName);