From 7ff8220e697e12e356f050b362b3be2e99ddd303 Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Tue, 8 Mar 2022 14:02:32 -0800 Subject: [PATCH] Fix | SqlDSEnumerator net core (#3) SqlDataSourceEnumerator test update and different file for unix, windows --- .../Interop/SNINativeMethodWrapper.Common.cs | 13 ------ .../Interop/SNINativeMethodWrapper.Windows.cs | 14 ++++++- .../src/Microsoft.Data.SqlClient.csproj | 10 +++-- .../Data/Sql/SqlDataSourceEnumerator.Unix.cs | 15 +++++++ .../netfx/src/Microsoft.Data.SqlClient.csproj | 3 ++ .../Sql/SqlDataSourceEnumerator.Windows.cs | 22 ++++++++++ .../Data/Sql/SqlDataSourceEnumerator.cs | 22 ++++------ .../SqlDataSourceEnumeratorManagedHelper.cs | 4 +- .../Microsoft.Data.SqlClient.Tests.csproj | 1 - .../SqlDataSourceEnumeratorTest.cs | 33 --------------- ....Data.SqlClient.ManualTesting.Tests.csproj | 5 ++- .../SqlDataSourceEnumeratorTest.cs | 40 +++++++++++++++++++ 12 files changed, 112 insertions(+), 70 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Unix.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs delete mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataSourceEnumeratorTest.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDSEnumeratorTest/SqlDataSourceEnumeratorTest.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs index 7f181d89d4..0b09ea3341 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Common.cs @@ -24,18 +24,5 @@ internal enum SniSpecialErrors : uint // max error code value MaxErrorValue = SNICommon.MaxErrorValue } - - [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumOpenWrapper")] - internal static extern IntPtr SNIServerEnumOpen(); - - [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumCloseWrapper")] - internal static extern void SNIServerEnumClose([In] IntPtr packet); - - [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper", CharSet = CharSet.Unicode)] - internal static extern int SNIServerEnumRead([In] IntPtr packet, - [In][MarshalAs(UnmanagedType.LPArray)] char[] readBuffer, - [In] int bufferLength, - [MarshalAs(UnmanagedType.Bool)] out bool more); - } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs index b49299d826..4e84fdc406 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs @@ -305,7 +305,19 @@ private static extern unsafe uint SNISecGenClientContextWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] private static extern uint SNIWriteSyncOverAsync(SNIHandle pConn, [In] SNIPacket pPacket); - #endregion + + [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumOpenWrapper")] + internal static extern IntPtr SNIServerEnumOpen(); + + [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumCloseWrapper")] + internal static extern void SNIServerEnumClose([In] IntPtr packet); + + [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIServerEnumReadWrapper", CharSet = CharSet.Unicode)] + internal static extern int SNIServerEnumRead([In] IntPtr packet, + [In][MarshalAs(UnmanagedType.LPArray)] char[] readBuffer, + [In] int bufferLength, + [MarshalAs(UnmanagedType.Bool)] out bool more); + #endregion internal static uint SniGetConnectionId(SNIHandle pConn, ref Guid connId) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 6f145b073a..ec72b3a856 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -51,9 +51,6 @@ Microsoft\Data\Sql\SqlDataSourceEnumeratorManagedHelper.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs @@ -645,6 +642,12 @@ + + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs + @@ -873,6 +876,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Unix.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Unix.cs new file mode 100644 index 0000000000..6ee3fe3329 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Unix.cs @@ -0,0 +1,15 @@ +// 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.Data; +using System.Data.Common; +using Microsoft.Data.SqlClient.Server; + +namespace Microsoft.Data.Sql +{ + /// + public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator + { + private partial DataTable GetDataSourcesInternal() => SqlDataSourceEnumeratorManagedHelper.GetDataSources(); + } +} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index e731eda557..fe4e7b13da 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -122,6 +122,9 @@ Microsoft\Data\Sql\SqlDataSourceEnumerator.cs + + Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs new file mode 100644 index 0000000000..83ce5085e7 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs @@ -0,0 +1,22 @@ +// 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.Data; +using System.Data.Common; +using Microsoft.Data.SqlClient.Server; + +namespace Microsoft.Data.Sql +{ + /// + public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator + { + private partial DataTable GetDataSourcesInternal() + { +#if NETFRAMEWORK + return SqlDataSourceEnumeratorNativeHelper.GetDataSources(); +#else + return SqlClient.TdsParserStateObjectFactory.UseManagedSNI ? SqlDataSourceEnumeratorManagedHelper.GetDataSources() : SqlDataSourceEnumeratorNativeHelper.GetDataSources(); +#endif + } + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs index 7f8393a360..e8f7aac29c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs @@ -4,30 +4,22 @@ using System; using System.Data; using System.Data.Common; -using Microsoft.Data.SqlClient.Server; namespace Microsoft.Data.Sql { /// - public sealed class SqlDataSourceEnumerator : DbDataSourceEnumerator + public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator { - private static readonly SqlDataSourceEnumerator s_singletonInstance = new(); + private static readonly Lazy s_singletonInstance = new(() => new SqlDataSourceEnumerator()); - private SqlDataSourceEnumerator() : base() - { - } + private SqlDataSourceEnumerator() : base(){} /// - public static SqlDataSourceEnumerator Instance => SqlDataSourceEnumerator.s_singletonInstance; + public static SqlDataSourceEnumerator Instance => s_singletonInstance.Value; /// - override public DataTable GetDataSources() - { -#if NETFRAMEWORK - return SqlDataSourceEnumeratorNativeHelper.GetDataSources(); -#else - return SqlClient.TdsParserStateObjectFactory.UseManagedSNI ? throw new NotImplementedException() : SqlDataSourceEnumeratorNativeHelper.GetDataSources(); -#endif - } + override public DataTable GetDataSources() => GetDataSourcesInternal(); + + private partial DataTable GetDataSourcesInternal(); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs index 02ed400aea..c2ab7dab19 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorManagedHelper.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Data; using Microsoft.Data.Sql; -using Microsoft.Data.SqlClient.SNI; namespace Microsoft.Data.SqlClient.Server { @@ -19,7 +18,8 @@ internal static class SqlDataSourceEnumeratorManagedHelper /// DataTable with ServerName,InstanceName,IsClustered and Version internal static DataTable GetDataSources() { - return ParseServerEnumString(SSRP.SendBroadcastUDPRequest()); + // TODO: Implement multicast request besides the implemented broadcast request. + throw new System.NotImplementedException(StringsHelper.net_MethodNotImplementedException); } private static DataTable ParseServerEnumString(string serverInstances) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index 79f679abf4..a9f2a1ef8d 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -47,7 +47,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataSourceEnumeratorTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataSourceEnumeratorTest.cs deleted file mode 100644 index 60215d27a6..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataSourceEnumeratorTest.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -using System; -using System.Data; -using System.ServiceProcess; -using Microsoft.Data.Sql; -using Xunit; - -namespace Microsoft.Data.SqlClient.Tests -{ - public class SqlDataSourceEnumeratorTest - { - [Fact] - [PlatformSpecific(TestPlatforms.Windows)] - public void SqlDataSourceEnumerator_VerfifyDataTableSize() - { - ServiceController sc = new("SQLBrowser"); - Assert.Equal(ServiceControllerStatus.Running, sc.Status); - - SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance; - if (AppContext.TryGetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", out bool isEnabled)) - { - Assert.Throws(() => instance.GetDataSources()); - } - else - { - DataTable table = instance.GetDataSources(); - Assert.NotEmpty(table.Rows); - } - } - } -} 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 ab9ad736bf..e08b05dc38 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 @@ -29,7 +29,7 @@ TCECryptoNativeBaselineRsa.txt - + @@ -158,6 +158,7 @@ + @@ -239,7 +240,7 @@ - + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDSEnumeratorTest/SqlDataSourceEnumeratorTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDSEnumeratorTest/SqlDataSourceEnumeratorTest.cs new file mode 100644 index 0000000000..c7bbb773b7 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDSEnumeratorTest/SqlDataSourceEnumeratorTest.cs @@ -0,0 +1,40 @@ +// 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.ServiceProcess; +using Microsoft.Data.Sql; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class SqlDataSourceEnumeratorTest + { + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsNotUsingManagedSNIOnWindows))] + [PlatformSpecific(TestPlatforms.Windows)] + public void SqlDataSourceEnumerator_NativeSNI() + { + // The returned rows depends on the running services which could be zero or more. + int count = GetDSEnumerator().GetDataSources().Rows.Count; + Assert.InRange(count, 0, 65536); + } + + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUsingManagedSNI))] + [PlatformSpecific(TestPlatforms.Windows)] + public void SqlDataSourceEnumerator_ManagedSNI() + { + // after adding the managed SNI support, this test should have the same result as SqlDataSourceEnumerator_NativeSNI + Assert.Throws(() => GetDSEnumerator().GetDataSources()); + } + + private SqlDataSourceEnumerator GetDSEnumerator() + { + ServiceController sc = new("SQLBrowser"); + Assert.Equal(ServiceControllerStatus.Running, sc.Status); + + return SqlDataSourceEnumerator.Instance; + } + } +}