Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test | Fix Unit Tests for GetSqlServerSPN #2442

Merged
merged 19 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8ddd3fc
Add fixes in SNIProxy to initialize InstanceName from data source.
arellegue Apr 3, 2024
f6f5d2e
Revert changes to Nuget.config.
arellegue Apr 3, 2024
3681b82
Applied suggestions in PR review.
arellegue Apr 3, 2024
940b4e7
Added comment for usage of port and use Trim() for all usage of token…
arellegue Apr 12, 2024
0f7c222
Added DataSource Parser Test of the DataTestUtility class.
arellegue Apr 12, 2024
a2f78d0
Added test cases of DataSource Parser with trailing, leading and embe…
arellegue Apr 12, 2024
76cd350
Reverted change to SNIProxy.cs so it no longer does force initializat…
arellegue Apr 26, 2024
b2ef4c5
Remove unused usings.
arellegue May 6, 2024
57ea9e6
Revert all changes in SNIProxy.cs.
arellegue May 10, 2024
00a5961
Remove blank line at line 722 in SNIProxy.cs.
arellegue May 10, 2024
0086bfb
Add comment that the instance name is set in the SNI Proxy object fro…
arellegue May 10, 2024
43dee59
Merged from upstream main.
arellegue May 24, 2024
291d3a7
Changed pre-processor NETCOREAPP to NET6_0_OR_GREATER.
arellegue May 24, 2024
8a87c72
Applied suggested change.
arellegue Jun 18, 2024
14c4b03
Merge branch 'main' into SPNPortNumberUnitTests
arellegue Jul 5, 2024
81c2891
Merge branch 'main' into SPNPortNumberUnitTests
arellegue Jul 16, 2024
050af61
Merge branch 'main' into SPNPortNumberUnitTests
arellegue Jul 30, 2024
df929e3
Merge remote-tracking branch 'upstream/main' into SPNPortNumberUnitTests
DavoudEshtehari Aug 23, 2024
d047321
Removed test case for named pipe protocol as the parsing for tcp pro…
arellegue Aug 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,9 @@ public static bool ParseDataSource(string dataSource, out string hostname, out i
port = -1;
instanceName = string.Empty;

// Remove leading and trailing spaces
dataSource = dataSource.Trim();

if (dataSource.Contains(":"))
{
dataSource = dataSource.Substring(dataSource.IndexOf(":", StringComparison.Ordinal) + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
<Compile Include="SQL\AADFedAuthTokenRefreshTest\AADFedAuthTokenRefreshTest.cs" />
<Compile Include="SQL\ConnectionPoolTest\ConnectionPoolTest.cs" />
<Compile Include="SQL\ConnectionPoolTest\PoolBlockPeriodTest.cs" />
<Compile Include="SQL\DataSourceParserTest\DataSourceParserTest.cs" />
<Compile Include="SQL\InstanceNameTest\InstanceNameTest.cs" />
<Compile Include="SQL\IntegratedAuthenticationTest\IntegratedAuthenticationTest.cs" />
<Compile Include="SQL\KerberosTests\KerberosTest.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// 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 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(" localhost ")]
[InlineData(" tcp:localhost ")]
[InlineData(" localhost")]
[InlineData(" tcp:localhost")]
[InlineData("localhost ")]
[InlineData("tcp: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(" localhost,1433 ")]
[InlineData(" tcp:localhost,1433 ")]
[InlineData(" localhost,1433")]
[InlineData(" tcp:localhost,1433")]
[InlineData("localhost,1433 ")]
[InlineData("tcp: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(" localhost\\MSSQLSERVER02 ")]
[InlineData(" tcp:localhost\\MSSQLSERVER02 ")]
[InlineData(" localhost\\MSSQLSERVER02")]
[InlineData(" tcp:localhost\\MSSQLSERVER02")]
[InlineData("localhost\\MSSQLSERVER02 ")]
[InlineData("tcp: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(" localhost\\MSSQLSERVER02,1433 ")]
[InlineData(" tcp:localhost\\MSSQLSERVER02,1433 ")]
[InlineData(" localhost\\MSSQLSERVER02,1433")]
[InlineData(" tcp:localhost\\MSSQLSERVER02,1433")]
[InlineData("localhost\\MSSQLSERVER02,1433 ")]
[InlineData("tcp: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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,9 +88,8 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove
}

#if NET6_0_OR_GREATER
[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);
Expand All @@ -98,11 +98,23 @@ 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;
cheenamalhotra marked this conversation as resolved.
Show resolved Hide resolved
SqlConnectionStringBuilder builder = new(connectionString);

DataTestUtility.ParseDataSource(builder.DataSource, out _, out _, out string instanceName);
arellegue marked this conversation as resolved.
Show resolved Hide resolved

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())
{
Expand All @@ -124,20 +136,27 @@ 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)
string spnInfo = GetSPNInfo(builder.DataSource, instanceName);
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);
}
}

private static string GetSPNInfo(string dataSource)
private static string GetSPNInfo(string dataSource, string inInstanceName)
{
Assembly sqlConnectionAssembly = Assembly.GetAssembly(typeof(SqlConnection));

Expand Down Expand Up @@ -178,9 +197,12 @@ 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();

// 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();
string instanceName = instanceNameInfo.GetValue(dataSrcInfo, null).ToString().ToUpper();

object port = getPortByInstanceNameInfo.Invoke(ssrpObj, parameters: new object[] { serverName, instanceName, timeoutTimerObj, false, 0 });

Expand All @@ -205,6 +227,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 = "";
Expand Down
Loading