Skip to content

Commit fd6c475

Browse files
author
Davoud Eshtehari
committed
Add test
1 parent ac69f38 commit fd6c475

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,16 +392,15 @@ void Cancel()
392392
Socket availableSocket = null;
393393
try
394394
{
395-
int n = 0; // Socket index
396-
397395
// We go through the IP list twice.
398396
// In the first traversal, we only try to connect with the preferedIPFamilies[0].
399397
// In the second traversal, we only try to connect with the preferedIPFamilies[1].
400398
// For UsePlatformDefault preference, we do traversal once.
401399
for (int i = 0; i < preferedIPFamilies.Length; ++i)
402400
{
403-
foreach (IPAddress ipAddress in ipAddresses)
401+
for (int n = 0; n < ipAddresses.Length; n++)
404402
{
403+
IPAddress ipAddress = ipAddresses[n];
405404
try
406405
{
407406
if (ipAddress != null)
@@ -443,7 +442,6 @@ void Cancel()
443442
sockets[n] = null;
444443
}
445444
}
446-
n++;
447445
}
448446
}
449447
catch (Exception e)

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/ConnectionHelper.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ internal static class ConnectionHelper
1717
private static Type s_dbConnectionInternal = s_MicrosoftDotData.GetType("Microsoft.Data.ProviderBase.DbConnectionInternal");
1818
private static Type s_tdsParser = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.TdsParser");
1919
private static Type s_tdsParserStateObject = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.TdsParserStateObject");
20+
private static Type s_SQLDNSInfo = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.SQLDNSInfo");
2021
private static PropertyInfo s_sqlConnectionInternalConnection = s_sqlConnection.GetProperty("InnerConnection", BindingFlags.Instance | BindingFlags.NonPublic);
2122
private static PropertyInfo s_dbConnectionInternalPool = s_dbConnectionInternal.GetProperty("Pool", BindingFlags.Instance | BindingFlags.NonPublic);
2223
private static MethodInfo s_dbConnectionInternalIsConnectionAlive = s_dbConnectionInternal.GetMethod("IsConnectionAlive", BindingFlags.Instance | BindingFlags.NonPublic);
@@ -26,6 +27,11 @@ internal static class ConnectionHelper
2627
private static FieldInfo s_tdsParserStateObjectProperty = s_tdsParser.GetField("_physicalStateObj", BindingFlags.Instance | BindingFlags.NonPublic);
2728
private static FieldInfo s_enforceTimeoutDelayProperty = s_tdsParserStateObject.GetField("_enforceTimeoutDelay", BindingFlags.Instance | BindingFlags.NonPublic);
2829
private static FieldInfo s_enforcedTimeoutDelayInMilliSeconds = s_tdsParserStateObject.GetField("_enforcedTimeoutDelayInMilliSeconds", BindingFlags.Instance | BindingFlags.NonPublic);
30+
private static FieldInfo s_pendingSQLDNSObject = s_sqlInternalConnectionTds.GetField("pendingSQLDNSObject", BindingFlags.Instance | BindingFlags.NonPublic);
31+
private static PropertyInfo s_pendingSQLDNS_FQDN = s_SQLDNSInfo.GetProperty("FQDN", BindingFlags.Instance | BindingFlags.Public);
32+
private static PropertyInfo s_pendingSQLDNS_AddrIPv4 = s_SQLDNSInfo.GetProperty("AddrIPv4", BindingFlags.Instance | BindingFlags.Public);
33+
private static PropertyInfo s_pendingSQLDNS_AddrIPv6 = s_SQLDNSInfo.GetProperty("AddrIPv6", BindingFlags.Instance | BindingFlags.Public);
34+
private static PropertyInfo s_pendingSQLDNS_Port = s_SQLDNSInfo.GetProperty("Port", BindingFlags.Instance | BindingFlags.Public);
2935

3036
public static object GetConnectionPool(object internalConnection)
3137
{
@@ -79,5 +85,17 @@ public static void SetEnforcedTimeout(this SqlConnection connection, bool enforc
7985
s_enforceTimeoutDelayProperty.SetValue(stateObj, enforce);
8086
s_enforcedTimeoutDelayInMilliSeconds.SetValue(stateObj, timeout);
8187
}
88+
89+
public static Tuple<string, string, string, string> GetSQLDNSInfo(this SqlConnection connection)
90+
{
91+
object internalConnection = GetInternalConnection(connection);
92+
VerifyObjectIsInternalConnection(internalConnection);
93+
object pendingSQLDNSInfo = s_pendingSQLDNSObject.GetValue(internalConnection);
94+
string fqdn = s_pendingSQLDNS_FQDN.GetValue(pendingSQLDNSInfo) as string;
95+
string ipv4 = s_pendingSQLDNS_AddrIPv4.GetValue(pendingSQLDNSInfo) as string;
96+
string ipv6 = s_pendingSQLDNS_AddrIPv6.GetValue(pendingSQLDNSInfo) as string;
97+
string port = s_pendingSQLDNS_Port.GetValue(pendingSQLDNSInfo) as string;
98+
return new Tuple<string, string, string, string>(fqdn, ipv4, ipv6, port);
99+
}
82100
}
83101
}

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConfigurableIpPreferenceTest/ConfigurableIpPreferenceTest.cs

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
7+
using System.Data;
8+
using System.Linq;
9+
using System.Net;
10+
using System.Net.Sockets;
611
using System.Reflection;
12+
using Microsoft.Data.SqlClient.ManualTesting.Tests.SystemDataInternals;
713
using Xunit;
814

915
using static Microsoft.Data.SqlClient.ManualTesting.Tests.DataTestUtility;
@@ -16,19 +22,68 @@ public class ConfigurableIpPreferenceTest
1622
private const string CnnPrefIPv6 = ";IPAddressPreference=IPv6First";
1723
private const string CnnPrefIPv4 = ";IPAddressPreference=IPv4First";
1824

25+
private static bool IsTCPConnectionStringSetup() => !string.IsNullOrEmpty(TCPConnectionString);
26+
private static bool IsValidDataSource()
27+
{
28+
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(TCPConnectionString);
29+
int startIdx = builder.DataSource.IndexOf(':') + 1;
30+
int endIdx = builder.DataSource.IndexOf(',');
31+
string serverName;
32+
if (endIdx == -1)
33+
{
34+
serverName = builder.DataSource.Substring(startIdx);
35+
}
36+
else
37+
{
38+
serverName = builder.DataSource.Substring(startIdx, endIdx - startIdx);
39+
}
40+
41+
List<IPAddress> ipAddresses = Dns.GetHostAddresses(serverName).ToList();
42+
return ipAddresses.Exists(ip => ip.AddressFamily == AddressFamily.InterNetwork) &&
43+
ipAddresses.Exists(ip => ip.AddressFamily == AddressFamily.InterNetworkV6);
44+
}
45+
46+
[ConditionalTheory(nameof(IsTCPConnectionStringSetup), nameof(IsValidDataSource))]
47+
[InlineData(CnnPrefIPv6)]
48+
[InlineData(CnnPrefIPv4)]
49+
[InlineData(";IPAddressPreference=UsePlatformDefault")]
50+
public void ConfigurableIpPreference(string ipPreference)
51+
{
52+
using (SqlConnection connection = new SqlConnection(TCPConnectionString + ipPreference))
53+
{
54+
connection.Open();
55+
Assert.Equal(ConnectionState.Open, connection.State);
56+
Tuple<string, string, string, string> DNSInfo = connection.GetSQLDNSInfo();
57+
if(ipPreference == CnnPrefIPv4)
58+
{
59+
Assert.NotNull(DNSInfo.Item2); //IPv4
60+
Assert.Null(DNSInfo.Item3); //IPv6
61+
}
62+
else if(ipPreference == CnnPrefIPv6)
63+
{
64+
Assert.Null(DNSInfo.Item2);
65+
Assert.NotNull(DNSInfo.Item3);
66+
}
67+
else
68+
{
69+
Assert.True((DNSInfo.Item2 != null && DNSInfo.Item3 == null) || (DNSInfo.Item2 == null && DNSInfo.Item3 != null));
70+
}
71+
}
72+
}
73+
1974
[ConditionalTheory(typeof(DataTestUtility), nameof(DoesHostAddressContainBothIPv4AndIPv6))]
2075
[InlineData(CnnPrefIPv6)]
2176
[InlineData(CnnPrefIPv4)]
2277
public void ConfigurableIpPreferenceManagedSni(string ipPreference)
2378
{
2479
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);
25-
TestConfigurableIpPreference(ipPreference);
80+
TestCachedConfigurableIpPreference(ipPreference, DNSCachingConnString);
2681
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", false);
2782
}
2883

29-
private void TestConfigurableIpPreference(string ipPreference)
84+
private void TestCachedConfigurableIpPreference(string ipPreference, string cnnString)
3085
{
31-
using (SqlConnection connection = new SqlConnection(DNSCachingConnString + ipPreference))
86+
using (SqlConnection connection = new SqlConnection(cnnString + ipPreference))
3287
{
3388
// each successful connection updates the dns cache entry for the data source
3489
connection.Open();
@@ -43,6 +98,7 @@ private void TestConfigurableIpPreference(string ipPreference)
4398
const string AddrIPv6Property = "AddrIPv6";
4499
const string FQDNProperty = "FQDN";
45100

101+
Assert.NotNull(dnsCacheEntry);
46102
Assert.Equal(connection.DataSource, GetPropertyValueFromCacheEntry(FQDNProperty, dnsCacheEntry));
47103

48104
if (ipPreference == CnnPrefIPv4)

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DNSCachingTest/DNSCachingTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using System;
66
using System.Collections.Generic;
7-
using System.Diagnostics;
87
using System.Reflection;
98
using Xunit;
109

0 commit comments

Comments
 (0)