diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs index e51175059a..49d68b0120 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SSRP.cs @@ -48,8 +48,14 @@ internal static int GetPortByInstanceName(string browserHostName, string instanc } catch (SocketException se) { + // A SocketException is possible for an instance name that doesn't exist. + // If there are multiple IP addresses and one of them fails with a SocketException but + // others simply don't respond because the instance name is invalid, we want to return + // the same error as if the response was empty. The higher error suits all scenarios. + // But log it, just in case there is a different, underlying issue that support needs + // to troubleshoot. SqlClientEventSource.Log.TrySNITraceEvent(nameof(SSRP), EventType.ERR, "SocketException Message = {0}", args0: se?.Message); - throw new Exception(SQLMessage.SqlServerBrowserNotAccessible(), se); + throw; } const byte SvrResp = 0x05; @@ -321,9 +327,37 @@ private static SsrpResult SendUDPRequest(IPEndPoint endPoint, byte[] requestPack } } } + catch (AggregateException ae) + { + if (ae.InnerExceptions.Count > 0) + { + // Log all errors + foreach (Exception e in ae.InnerExceptions) + { + // Favor SocketException for returned error + if (e is SocketException) + { + result.Error = e; + } + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SSRP), EventType.INFO, + "SendUDPRequest ({0}) resulted in exception: {1}", args0: endPoint.ToString(), args1: e.Message); + } + + // Return first error if we didn't find a SocketException + result.Error = result.Error == null ? ae.InnerExceptions[0] : result.Error; + } + else + { + result.Error = ae; + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SSRP), EventType.INFO, + "SendUDPRequest ({0}) resulted in exception: {1}", args0: endPoint.ToString(), args1: ae.Message); + } + } catch (Exception e) { result.Error = e; + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SSRP), EventType.INFO, + "SendUDPRequest ({0}) resulted in exception: {1}", args0: endPoint.ToString(), args1: e.Message); } return result; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs index 4aebe4b518..0947d6d849 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -1984,10 +1984,6 @@ internal static string SSPIGenerateError() { return StringsHelper.GetString(Strings.SQL_SSPIGenerateError); } - internal static string SqlServerBrowserNotAccessible() - { - return StringsHelper.GetString(Strings.SQL_SqlServerBrowserNotAccessible); - } internal static string KerberosTicketMissingError() { return StringsHelper.GetString(Strings.SQL_KerberosTicketMissingError); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs index 21e213b262..bba9987634 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs @@ -3201,15 +3201,6 @@ internal static string SQL_SqlCommandCommandText { } } - /// - /// Looks up a localized string similar to Cannot connect to SQL Server Browser. Ensure SQL Server Browser has been started.. - /// - internal static string SQL_SqlServerBrowserNotAccessible { - get { - return ResourceManager.GetString("SQL_SqlServerBrowserNotAccessible", resourceCulture); - } - } - /// /// Looks up a localized string similar to Failed to generate SSPI context.. /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx index b9bbac1567..28999773e0 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx @@ -537,9 +537,6 @@ Cannot authenticate using Kerberos. Ensure Kerberos has been initialized on the client with 'kinit' and a Service Principal Name has been registered for the SQL Server to allow Kerberos authentication. - - Cannot connect to SQL Server Browser. Ensure SQL Server Browser has been started. - Invalid SSPI packet size. diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs index bd6060c179..62db90fce0 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs @@ -57,7 +57,7 @@ public ApiShould(PlatformSpecificTestContext context) DummyKeyStoreProvider.Name, _lastTenBytesCek); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithBooleanVariable))] public void TestSqlTransactionCommitRollbackWithTransparentInsert(string connection, bool isCommitted) { @@ -94,7 +94,7 @@ public void TestSqlTransactionCommitRollbackWithTransparentInsert(string connect } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestSqlTransactionRollbackToSavePoint(string connection) { @@ -140,7 +140,7 @@ public void TestSqlTransactionRollbackToSavePoint(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void SqlParameterProperties(string connection) { @@ -351,7 +351,7 @@ public void SqlParameterProperties(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestSqlDataAdapterFillDataTable(string connection) { @@ -424,7 +424,7 @@ public void TestSqlDataAdapterFillDataTable(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithSchemaType))] public void TestSqlDataAdapterFillSchema(string connection, SchemaType schemaType) { @@ -471,7 +471,7 @@ private void ValidateSchema(DataColumnCollection dataColumns) Assert.Equal(typeof(string), dataColumns[2].DataType); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithBooleanVariable))] public void TestExecuteNonQuery(string connection, bool isAsync) { @@ -539,7 +539,7 @@ public void TestExecuteNonQuery(string connection, bool isAsync) }); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithBooleanVariable))] public void TestExecuteScalar(string connection, bool isAsync) { @@ -591,7 +591,7 @@ public void TestExecuteScalar(string connection, bool isAsync) }); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithIntegers))] public void TestSqlDataAdapterBatchUpdate(string connection, int numberofRows) { @@ -636,7 +636,7 @@ public void TestSqlDataAdapterBatchUpdate(string connection, int numberofRows) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestExecuteReader(string connection) { @@ -690,7 +690,7 @@ public void TestExecuteReader(string connection) }); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public async void TestExecuteReaderAsyncWithLargeQuery(string connectionString) { @@ -743,7 +743,7 @@ public async void TestExecuteReaderAsyncWithLargeQuery(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithCommandBehaviorSet1))] public void TestExecuteReaderWithCommandBehavior(string connection, CommandBehavior commandBehavior) { @@ -868,7 +868,7 @@ public void TestExecuteReaderWithCommandBehavior(string connection, CommandBehav }); } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestEnclaveStoredProceduresWithAndWithoutParameters(string connectionString) { @@ -915,7 +915,7 @@ public void TestEnclaveStoredProceduresWithAndWithoutParameters(string connectio } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestPrepareWithExecuteNonQuery(string connection) { @@ -964,7 +964,7 @@ public void TestPrepareWithExecuteNonQuery(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestAsyncWriteDelayWithExecuteNonQueryAsync(string connection) { @@ -1018,7 +1018,7 @@ public void TestAsyncWriteDelayWithExecuteNonQueryAsync(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestAsyncWriteDelayWithExecuteReaderAsync(string connection) { @@ -1085,7 +1085,7 @@ public void TestAsyncWriteDelayWithExecuteReaderAsync(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestPrepareWithExecuteNonQueryAsync(string connection) { @@ -1140,7 +1140,7 @@ public void TestPrepareWithExecuteNonQueryAsync(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithCommandBehaviorSet2))] public void TestPrepareWithExecuteReaderAsync(string connection, CommandBehavior commandBehavior) { @@ -1202,7 +1202,7 @@ public void TestPrepareWithExecuteReaderAsync(string connection, CommandBehavior } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestSqlDataReaderAPIs(string connection) { @@ -1399,7 +1399,7 @@ public void TestSqlDataReaderAPIs(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestSqlDataReaderAPIsWithSequentialAccess(string connection) { @@ -1827,7 +1827,7 @@ public void TestSqlDataReaderAPIsWithSequentialAccess(string connection) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithCommandBehaviorSet2))] public void TestSqlCommandSequentialAccessCodePaths(string connection, CommandBehavior value) { @@ -1871,7 +1871,7 @@ public void TestSqlCommandSequentialAccessCodePaths(string connection, CommandBe } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestExecuteXmlReader(string connection) { @@ -2126,7 +2126,7 @@ public void TestSqlCommandCancel(string connection, string value, int number) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProviderWithCancellationTime))] public void TestSqlCommandCancellationToken(string connection, int initalValue, int cancellationTime) { @@ -2194,7 +2194,7 @@ public void TestNoneAttestationProtocolWithSGXEnclave() } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestConnectionCustomKeyStoreProviderDuringAeQuery(string connectionString) { @@ -2249,7 +2249,7 @@ public void TestConnectionCustomKeyStoreProviderDuringAeQuery(string connectionS } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE), nameof(DataTestUtility.IsAKVSetupAvailable))] [ClassData(typeof(AEConnectionStringProvider))] public void TestCommandCustomKeyStoreProviderDuringAeQuery(string connectionString) { @@ -2300,7 +2300,7 @@ public void TestCommandCustomKeyStoreProviderDuringAeQuery(string connectionStri // On Windows, "_fixture" will be type SQLSetupStrategyCertStoreProvider // On non-Windows, "_fixture" will be type SQLSetupStrategyAzureKeyVault // Test will pass on both but only SQLSetupStrategyCertStoreProvider is a system provider - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestSystemProvidersHavePrecedenceOverInstanceLevelProviders(string connectionString) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs index 6a58935cff..20cd452286 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs @@ -24,7 +24,7 @@ public BulkCopyAE(PlatformSpecificTestContext context) tableName = fixture.BulkCopyAETestTable.Name; } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TestBulkCopyString(string connectionString) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs index cf2da1c4b6..9d6080b24f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs @@ -25,7 +25,7 @@ public BulkCopyAEErrorMessage(PlatformSpecificTestContext context) _columnName = "c1"; } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void TextToIntErrorMessageTest(string connectionString) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs index 4862a41d03..ea4b0171eb 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs @@ -24,7 +24,7 @@ public End2EndSmokeTests(PlatformSpecificTestContext context) } // tests - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(TestSelectOnEncryptedNonEncryptedColumnsData))] public void TestSelectOnEncryptedNonEncryptedColumns(string connString, string selectQuery, int totalColumnsInSelect, string[] types) { @@ -58,7 +58,7 @@ public void TestSelectOnEncryptedNonEncryptedColumns(string connString, string s } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(TestSelectOnEncryptedNonEncryptedColumnsWithEncryptedParametersData))] public void TestSelectOnEncryptedNonEncryptedColumnsWithEncryptedParameters(string connString, bool sync, diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs index 32dd86cd94..e5c4429752 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs @@ -23,7 +23,7 @@ public SqlBulkCopyTruncation(PlatformSpecificTestContext context) tableNames = _fixture.sqlBulkTruncationTableNames; } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyTestsInt(string connectionString) { @@ -40,7 +40,7 @@ public void BulkCopyTestsInt(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void DirectInsertTest1(string connectionString) { @@ -80,7 +80,7 @@ public void DirectInsertTest1(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void DirectInsertTest2(string connectionString) { @@ -127,7 +127,7 @@ public void DirectInsertTest2(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void DirectInsertTest3(string connectionString) { @@ -172,7 +172,7 @@ public void DirectInsertTest3(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void DirectInsertTest4(string connectionString) { @@ -209,7 +209,7 @@ public void DirectInsertTest4(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyDatetime2Tests(string connectionString) { @@ -258,7 +258,7 @@ public void BulkCopyDatetime2Tests(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyDecimal(string connectionString) { @@ -275,7 +275,7 @@ public void BulkCopyDecimal(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyVarchar(string connectionString) { @@ -304,7 +304,7 @@ public void BulkCopyVarchar(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyVarcharMax(string connectionString) { @@ -333,7 +333,7 @@ public void BulkCopyVarcharMax(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyNVarchar(string connectionString) { @@ -350,7 +350,7 @@ public void BulkCopyNVarchar(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyNVarcharMax(string connectionString) { @@ -367,7 +367,7 @@ public void BulkCopyNVarcharMax(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopyBinaryMax(string connectionString) { @@ -407,7 +407,7 @@ public void BulkCopyBinaryMax(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopySmallBinary(string connectionString) { @@ -476,7 +476,7 @@ public void BulkCopySmallBinary(string connectionString) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(AEConnectionStringProvider))] public void BulkCopySmallChar(string connectionString) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs index 2f1a1d8ed6..ed3d9797dd 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs @@ -56,7 +56,7 @@ public SqlNullValuesTests(PlatformSpecificTestContext context) } } - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsTargetReadyForAeWithKeyStore))] [ClassData(typeof(NullValueTestsData))] public void NullValueTests(string connString, ConnStringColumnEncryptionSetting connStringSetting, SqlCommandColumnEncryptionSetting commandSetting, ReturnValueSetting nullReturnValue) { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 1d4c0adf6b..4853806246 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -341,6 +341,16 @@ public static bool IsAKVSetupAvailable() return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(AKVClientId) && !string.IsNullOrEmpty(AKVClientSecret) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse(); } + public static bool IsTargetReadyForAeWithKeyStore() + { + return DataTestUtility.AreConnStringSetupForAE() +#if NET6_0_OR_GREATER + // AE tests on Windows will use the Cert Store. On non-Windows, they require AKV. + && (OperatingSystem.IsWindows() || DataTestUtility.IsAKVSetupAvailable()) +#endif + ; + } + public static bool IsUsingManagedSNI() => UseManagedSNIOnWindows; public static bool IsNotUsingManagedSNIOnWindows() => !UseManagedSNIOnWindows; @@ -946,15 +956,24 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) /// Resolves the machine's fully qualified domain name if it is applicable. /// /// Returns FQDN if the client was domain joined otherwise the machine name. - public static string GetMachineFQDN() + public static string GetMachineFQDN(string hostname) { IPGlobalProperties machineInfo = IPGlobalProperties.GetIPGlobalProperties(); StringBuilder fqdn = new(); - fqdn.Append(machineInfo.HostName); - if (!string.IsNullOrEmpty(machineInfo.DomainName)) + if (hostname.Equals("localhost", StringComparison.OrdinalIgnoreCase) || + hostname.Equals(machineInfo.HostName, StringComparison.OrdinalIgnoreCase)) + { + fqdn.Append(machineInfo.HostName); + if (!string.IsNullOrEmpty(machineInfo.DomainName)) + { + fqdn.Append("."); + fqdn.Append(machineInfo.DomainName); + } + } + else { - fqdn.Append("."); - fqdn.Append(machineInfo.DomainName); + IPHostEntry host = Dns.GetHostEntry(hostname); + fqdn.Append(host.HostName); } return fqdn.ToString(); } 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 6edc9f00a6..1ae87217b6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -33,7 +33,10 @@ public static void ConnectToSQLWithInstanceNameTest() connection.Open(); connection.Close(); - if (builder.Encrypt != SqlConnectionEncryptOption.Strict) + // We can only connect via IP address if we aren't doing remote Kerberos or strict TLS + if (builder.Encrypt != SqlConnectionEncryptOption.Strict && + (!builder.IntegratedSecurity || hostname.Equals("localhost", StringComparison.OrdinalIgnoreCase) || + hostname.Equals(Environment.MachineName, StringComparison.OrdinalIgnoreCase))) { // Exercise the IP address-specific code in SSRP IPAddress[] addresses = Dns.GetHostAddresses(hostname); @@ -64,7 +67,6 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove if (IsBrowserAlive(hostname) && IsValidInstance(hostname, instanceName)) { builder.DataSource = hostname + "\\" + instanceName; - using SqlConnection connection = new(builder.ConnectionString); connection.Open(); } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs index 6cd19714ae..654d020742 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs @@ -46,7 +46,13 @@ public static void IntegratedAuthenticationTest_ServerSPN() { SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); builder.IntegratedSecurity = true; - builder.ServerSPN = $"MSSQLSvc/{DataTestUtility.GetMachineFQDN()}"; + Assert.True(DataTestUtility.ParseDataSource(builder.DataSource, out string hostname, out int port, out string instanceName)); + // Build the SPN for the server we are connecting to + builder.ServerSPN = $"MSSQLSvc/{DataTestUtility.GetMachineFQDN(hostname)}"; + if (!string.IsNullOrWhiteSpace(instanceName)) + { + builder.ServerSPN += ":" + instanceName; + } TryOpenConnectionWithIntegratedAuthentication(builder.ConnectionString); }