diff --git a/src/System.Data.SqlClient/src/Interop/SNINativeMethodWrapper.Windows.cs b/src/System.Data.SqlClient/src/Interop/SNINativeMethodWrapper.Windows.cs index 1902b7045a8e..e6e43a382ceb 100644 --- a/src/System.Data.SqlClient/src/Interop/SNINativeMethodWrapper.Windows.cs +++ b/src/System.Data.SqlClient/src/Interop/SNINativeMethodWrapper.Windows.cs @@ -197,7 +197,7 @@ internal struct SNI_Error internal static extern void SNIPacketRelease(IntPtr pPacket); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNIPacketResetWrapper")] - internal static extern void SNIPacketReset([In] SNIHandle pConn, IOType IOType, SNIPacket pPacket, ConsumerNumber ConsNum); + internal static extern void SNIPacketReset([In] SNIHandle pConn, IOType IOType, SNIPacketHandle pPacket, ConsumerNumber ConsNum); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] internal static extern uint SNIQueryInfo(QTypes QType, ref uint pbQInfo); @@ -256,7 +256,7 @@ private static extern uint SNIOpenWrapper( private static extern uint SNIPacketGetDataWrapper([In] IntPtr packet, [In, Out] byte[] readBuffer, uint readBufferLength, out uint dataSize); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] - private static extern unsafe void SNIPacketSetData(SNIPacket pPacket, [In] byte* pbBuf, uint cbBuf); + private static extern unsafe void SNIPacketSetData(SNIPacketHandle pPacket, [In] byte* pbBuf, uint cbBuf); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe uint SNISecGenClientContextWrapper( @@ -272,10 +272,10 @@ private static extern unsafe uint SNISecGenClientContextWrapper( [MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszPassword); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] - private static extern uint SNIWriteAsyncWrapper(SNIHandle pConn, [In] SNIPacket pPacket); + private static extern uint SNIWriteAsyncWrapper(SNIHandle pConn, [In] SNIPacketHandle pPacket); [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] - private static extern uint SNIWriteSyncOverAsync(SNIHandle pConn, [In] SNIPacket pPacket); + private static extern uint SNIWriteSyncOverAsync(SNIHandle pConn, [In] SNIPacketHandle pPacket); #endregion internal static uint SniGetConnectionId(SNIHandle pConn, ref Guid connId) @@ -347,7 +347,7 @@ internal static unsafe uint SNIPacketGetData(IntPtr packet, byte[] readBuffer, r return SNIPacketGetDataWrapper(packet, readBuffer, (uint)readBuffer.Length, out dataSize); } - internal static unsafe void SNIPacketSetData(SNIPacket packet, byte[] data, int length) + internal static unsafe void SNIPacketSetData(SNIPacketHandle packet, byte[] data, int length) { fixed (byte* pin_data = &data[0]) { @@ -374,7 +374,7 @@ internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, } } - internal static uint SNIWritePacket(SNIHandle pConn, SNIPacket packet, bool sync) + internal static uint SNIWritePacket(SNIHandle pConn, SNIPacketHandle packet, bool sync) { if (sync) { diff --git a/src/System.Data.SqlClient/src/System.Data.SqlClient.csproj b/src/System.Data.SqlClient/src/System.Data.SqlClient.csproj index a288a3ed5c6a..98cd905bab95 100644 --- a/src/System.Data.SqlClient/src/System.Data.SqlClient.csproj +++ b/src/System.Data.SqlClient/src/System.Data.SqlClient.csproj @@ -9,6 +9,7 @@ 4.0.0.0 4.1.0.0 $(DefineConstants);netcoreapp + $(DefineConstants);snidll $(DefineConstants);FEATURE_TCPKEEPALIVE net461-Windows_NT-Debug;net461-Windows_NT-Release;netcoreapp-Debug;netcoreapp-Release;netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netcoreapp2.1-Debug;netcoreapp2.1-Release;netcoreapp2.1-Unix-Debug;netcoreapp2.1-Unix-Release;netcoreapp2.1-Windows_NT-Debug;netcoreapp2.1-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;netstandard-Debug;netstandard-Release;netstandard-Unix-Debug;netstandard-Unix-Release;netstandard-Windows_NT-Debug;netstandard-Windows_NT-Release;netstandard1.2-Debug;netstandard1.2-Release;netstandard1.3-Debug;netstandard1.3-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;uap10.0.16299-Windows_NT-Debug;uap10.0.16299-Windows_NT-Release diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIMarsHandle.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIMarsHandle.cs index 4d079f6ad0bb..e9fd64f12d52 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIMarsHandle.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIMarsHandle.cs @@ -317,7 +317,7 @@ public void HandleReceiveError(SNIPacket packet) _packetEvent.Set(); } - ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 1); + ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 1); } /// @@ -331,7 +331,7 @@ public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { Debug.Assert(_callbackObject != null); - ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(packet, sniErrorCode); + ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(PacketHandle.FromManagedPacket(packet), sniErrorCode); } } @@ -377,7 +377,7 @@ public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header) _asyncReceives--; Debug.Assert(_callbackObject != null); - ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 0); + ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 0); } } diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIPacket.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIPacket.cs index 84a47740fabf..acc03819182e 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIPacket.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNIPacket.cs @@ -20,8 +20,6 @@ internal class SNIPacket : IDisposable, IEquatable private int _offset; private string _description; private SNIAsyncCallback _completionCallback; - - private ArrayPool _arrayPool = ArrayPool.Shared; private bool _isBufferFromArrayPool = false; public SNIPacket() { } @@ -98,14 +96,14 @@ public void Allocate(int capacity) { if (_isBufferFromArrayPool) { - _arrayPool.Return(_data); + ArrayPool.Shared.Return(_data); } _data = null; } if (_data == null) { - _data = _arrayPool.Rent(capacity); + _data = ArrayPool.Shared.Rent(capacity); _isBufferFromArrayPool = true; } @@ -221,7 +219,7 @@ public void Release() { if(_isBufferFromArrayPool) { - _arrayPool.Return(_data); + ArrayPool.Shared.Return(_data); } _data = null; _capacity = 0; diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.Windows.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.Windows.cs index 12ce515bf93d..3c889c959bb1 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.Windows.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.Windows.cs @@ -20,20 +20,22 @@ internal void PostReadAsyncForMars() // Have to post read to initialize MARS - will get callback on this when connection goes // down or is closed. - IntPtr temp = IntPtr.Zero; + PacketHandle temp = default; uint error = TdsEnums.SNI_SUCCESS; _pMarsPhysicalConObj.IncrementPendingCallbacks(); - object handle = _pMarsPhysicalConObj.SessionHandle; - temp = (IntPtr)_pMarsPhysicalConObj.ReadAsync(out error, ref handle); + SessionHandle handle = _pMarsPhysicalConObj.SessionHandle; + temp = _pMarsPhysicalConObj.ReadAsync(handle, out error); - if (temp != IntPtr.Zero) + Debug.Assert(temp.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + + if (temp.NativePointer != IntPtr.Zero) { // Be sure to release packet, otherwise it will be leaked by native. _pMarsPhysicalConObj.ReleasePacket(temp); } - Debug.Assert(IntPtr.Zero == temp, "unexpected syncReadPacket without corresponding SNIPacketRelease"); + Debug.Assert(IntPtr.Zero == temp.NativePointer, "unexpected syncReadPacket without corresponding SNIPacketRelease"); if (TdsEnums.SNI_SUCCESS_IO_PENDING != error) { Debug.Assert(TdsEnums.SNI_SUCCESS != error, "Unexpected successful read async on physical connection before enabling MARS!"); @@ -118,4 +120,4 @@ private SNIErrorDetails GetSniErrorDetails() } } // tdsparser -}//namespace \ No newline at end of file +}//namespace diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserSafeHandles.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserSafeHandles.cs index 55cd8a1c5fb5..4360ab64d5ab 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserSafeHandles.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserSafeHandles.cs @@ -104,7 +104,7 @@ private static void ReadDispatcher(IntPtr key, IntPtr packet, uint error) if (null != stateObj) { - stateObj.ReadAsyncCallback(IntPtr.Zero, packet, error); + stateObj.ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromNativePointer(packet), error); } } } @@ -125,7 +125,7 @@ private static void WriteDispatcher(IntPtr key, IntPtr packet, uint error) if (null != stateObj) { - stateObj.WriteAsyncCallback(IntPtr.Zero, packet, error); + stateObj.WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromNativePointer(packet), error); } } } @@ -206,9 +206,9 @@ internal uint Status } } - internal sealed class SNIPacket : SafeHandle + internal sealed class SNIPacketHandle : SafeHandle { - internal SNIPacket(SafeHandle sniHandle) : base(IntPtr.Zero, true) + internal SNIPacketHandle(SafeHandle sniHandle) : base(IntPtr.Zero, true) { SNINativeMethodWrapper.SNIPacketAllocate(sniHandle, SNINativeMethodWrapper.IOType.WRITE, ref base.handle); if (IntPtr.Zero == base.handle) @@ -241,17 +241,17 @@ override protected bool ReleaseHandle() internal sealed class WritePacketCache : IDisposable { private bool _disposed; - private Stack _packets; + private Stack _packets; public WritePacketCache() { _disposed = false; - _packets = new Stack(); + _packets = new Stack(); } - public SNIPacket Take(SNIHandle sniHandle) + public SNIPacketHandle Take(SNIHandle sniHandle) { - SNIPacket packet; + SNIPacketHandle packet; if (_packets.Count > 0) { // Success - reset the packet @@ -261,12 +261,12 @@ public SNIPacket Take(SNIHandle sniHandle) else { // Failed to take a packet - create a new one - packet = new SNIPacket(sniHandle); + packet = new SNIPacketHandle(sniHandle); } return packet; } - public void Add(SNIPacket packet) + public void Add(SNIPacketHandle packet) { if (!_disposed) { @@ -296,4 +296,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObject.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObject.cs index dcc7eae1744e..e74c3179476e 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObject.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObject.cs @@ -20,6 +20,102 @@ sealed internal class LastIOTimer internal long _value; } + internal readonly ref struct PacketHandle + { + public const int NativePointerType = 1; + public const int NativePacketType = 2; + public const int ManagedPacketType = 3; + +#if snidll + public readonly IntPtr NativePointer; + public readonly SNIPacketHandle NativePacket; +#endif + public readonly SNI.SNIPacket ManagedPacket; + public readonly int Type; + + private PacketHandle(IntPtr nativePointer, +#if snidll + SNIPacketHandle +#else + int +#endif + + nativePacket, SNI.SNIPacket managedPacket,int type) + { + Type = type; + ManagedPacket = managedPacket; +#if snidll + NativePointer = nativePointer; + NativePacket = nativePacket; +#endif + } + + public static PacketHandle FromManagedPacket(SNI.SNIPacket managedPacket) + { + return new PacketHandle(default, default, managedPacket, ManagedPacketType); + } + +#if snidll + public static PacketHandle FromNativePointer(IntPtr nativePointer) + { + return new PacketHandle(nativePointer,default,default, NativePointerType); + } + + public static PacketHandle FromNativePacket(SNIPacketHandle nativePacket) + { + return new PacketHandle(default, nativePacket, default, NativePacketType); + } +#endif + + + } + + internal readonly ref struct SessionHandle + { + public const int NativeHandleType = 1; + public const int ManagedHandleType = 2; + + public readonly SNI.SNIHandle ManagedHandle; +#if snidll + public readonly SNIHandle NativeHandle; +#endif + public readonly int Type; + + public SessionHandle(SNI.SNIHandle managedHandle, +#if snidll + SNIHandle +#else + int +#endif + nativeHandle, + int type + ) + { + Type = type; + ManagedHandle = managedHandle; +#if snidll + NativeHandle = nativeHandle; +#endif + } + + public bool IsNull => +#if snidll + (Type == NativeHandleType) ? NativeHandle == null : +#endif + ManagedHandle == null; + + public static SessionHandle FromManagedSession(SNI.SNIHandle managedSessionHandle) + { + return new SessionHandle(managedSessionHandle, default, ManagedHandleType); + } +#if snidll + public static SessionHandle FromNativeHandle(SNIHandle nativeSessionHandle) + { + return new SessionHandle(default, nativeSessionHandle, NativeHandleType); + } +#endif + } + internal abstract class TdsParserStateObject { private const int AttentionTimeoutSeconds = 5; @@ -392,7 +488,7 @@ internal abstract uint Status get; } - internal abstract object SessionHandle + internal abstract SessionHandle SessionHandle { get; } @@ -761,27 +857,27 @@ private void ResetCancelAndProcessAttention() internal abstract void DisposePacketCache(); - internal abstract bool IsPacketEmpty(object readPacket); + internal abstract bool IsPacketEmpty(PacketHandle readPacket); - internal abstract object ReadSyncOverAsync(int timeoutRemaining, out uint error); + internal abstract PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error); - internal abstract object ReadAsync(out uint error, ref object handle); + internal abstract PacketHandle ReadAsync(SessionHandle handle, out uint error); internal abstract uint CheckConnection(); internal abstract uint SetConnectionBufferSize(ref uint unsignedPacketSize); - internal abstract void ReleasePacket(object syncReadPacket); + internal abstract void ReleasePacket(PacketHandle syncReadPacket); - protected abstract uint SNIPacketGetData(object packet, byte[] _inBuff, ref uint dataSize); + protected abstract uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize); - internal abstract object GetResetWritePacket(); + internal abstract PacketHandle GetResetWritePacket(); internal abstract void ClearAllWritePackets(); - internal abstract object AddPacketToPendingList(object packet); + internal abstract PacketHandle AddPacketToPendingList(PacketHandle packet); - protected abstract void RemovePacketFromPendingList(object pointer); + protected abstract void RemovePacketFromPendingList(PacketHandle pointer); internal abstract uint GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[] _sniSpnBuffer); @@ -855,7 +951,7 @@ internal int DecrementPendingCallbacks(bool release) // NOTE: TdsParserSessionPool may call DecrementPendingCallbacks on a TdsParserStateObject which is already disposed // This is not dangerous (since the stateObj is no longer in use), but we need to add a workaround in the assert for it - Debug.Assert((remaining == -1 && SessionHandle == null) || (0 <= remaining && remaining < 3), string.Format("_pendingCallbacks values is invalid after decrementing: {0}", remaining)); + Debug.Assert((remaining == -1 && SessionHandle.IsNull ) || (0 <= remaining && remaining < 3), string.Format("_pendingCallbacks values is invalid after decrementing: {0}", remaining)); return remaining; } @@ -2069,7 +2165,7 @@ internal void ReadSniSyncOverAsync() throw ADP.ClosedConnectionError(); } - object readPacket = null; + PacketHandle readPacket = default; uint error; @@ -2291,7 +2387,7 @@ internal void ReadSni(TaskCompletionSource completion) #endif - object readPacket = null; + PacketHandle readPacket = default; uint error = 0; @@ -2317,16 +2413,14 @@ internal void ReadSni(TaskCompletionSource completion) ChangeNetworkPacketTimeout(msecsRemaining, Timeout.Infinite); } - object handle = null; - Interlocked.Increment(ref _readingCount); - handle = SessionHandle; - if (handle != null) + SessionHandle handle = SessionHandle; + if (!handle.IsNull) { IncrementPendingCallbacks(); - readPacket = ReadAsync(out error, ref handle); + readPacket = ReadAsync(handle, out error); if (!(TdsEnums.SNI_SUCCESS == error || TdsEnums.SNI_SUCCESS_IO_PENDING == error)) { @@ -2336,7 +2430,7 @@ internal void ReadSni(TaskCompletionSource completion) Interlocked.Decrement(ref _readingCount); - if (handle == null) + if (handle.IsNull) { throw ADP.ClosedConnectionError(); } @@ -2419,7 +2513,7 @@ internal bool IsConnectionAlive(bool throwOnException) { uint error; - object readPacket = EmptyReadPacket; + PacketHandle readPacket = EmptyReadPacket; try { @@ -2512,7 +2606,7 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error) { stateObj.SendAttention(mustTakeWriteLock: true); - object syncReadPacket = null; + PacketHandle syncReadPacket = default; bool shouldDecrement = false; try @@ -2584,7 +2678,7 @@ private void ReadSniError(TdsParserStateObject stateObj, uint error) AssertValidState(); } - public void ProcessSniPacket(object packet, uint error) + public void ProcessSniPacket(PacketHandle packet, uint error) { if (error != 0) { @@ -2683,13 +2777,13 @@ private void SetBufferSecureStrings() } } - public void ReadAsyncCallback(T packet, uint error) + public void ReadAsyncCallback(PacketHandle packet, uint error) { ReadAsyncCallback(IntPtr.Zero, packet, error); } - public void ReadAsyncCallback(IntPtr key, T packet, uint error) + public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error) { // Key never used. // Note - it's possible that when native calls managed that an asynchronous exception @@ -2769,7 +2863,7 @@ public void ReadAsyncCallback(IntPtr key, T packet, uint error) } } - protected abstract bool CheckPacket(object packet, TaskCompletionSource source); + protected abstract bool CheckPacket(PacketHandle packet, TaskCompletionSource source); private void ReadAsyncCallbackCaptureException(TaskCompletionSource source) { @@ -2815,12 +2909,12 @@ private void ReadAsyncCallbackCaptureException(TaskCompletionSource sour #pragma warning disable 0420 // a reference to a volatile field will not be treated as volatile - public void WriteAsyncCallback(T packet, uint sniError) + public void WriteAsyncCallback(PacketHandle packet, uint sniError) { WriteAsyncCallback(IntPtr.Zero, packet, sniError); } - public void WriteAsyncCallback(IntPtr key, T packet, uint sniError) + public void WriteAsyncCallback(IntPtr key, PacketHandle packet, uint sniError) { // Key never used. RemovePacketFromPendingList(packet); try @@ -3189,7 +3283,7 @@ private void CancelWritePacket() #pragma warning disable 0420 // a reference to a volatile field will not be treated as volatile - private Task SNIWritePacket(object packet, out uint sniError, bool canAccumulate, bool callerHasConnectionLock) + private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccumulate, bool callerHasConnectionLock) { // Check for a stored exception var delayedException = Interlocked.Exchange(ref _delayedWriteAsyncCallbackException, null); @@ -3201,7 +3295,7 @@ private Task SNIWritePacket(object packet, out uint sniError, bool canAccumulate Task task = null; _writeCompletionSource = null; - object packetPointer = EmptyReadPacket; + PacketHandle packetPointer = EmptyReadPacket; bool sync = !_parser._asyncWrite; if (sync && _asyncWriteCount > 0) @@ -3322,8 +3416,8 @@ private Task SNIWritePacket(object packet, out uint sniError, bool canAccumulate return task; } - internal abstract bool IsValidPacket(object packetPointer); - internal abstract uint WritePacket(object packet, bool sync); + internal abstract bool IsValidPacket(PacketHandle packetPointer); + internal abstract uint WritePacket(PacketHandle packet, bool sync); #pragma warning restore 0420 @@ -3340,7 +3434,7 @@ internal void SendAttention(bool mustTakeWriteLock = false) return; } - object attnPacket = CreateAndSetAttentionPacket(); + PacketHandle attnPacket = CreateAndSetAttentionPacket(); try { @@ -3398,14 +3492,14 @@ internal void SendAttention(bool mustTakeWriteLock = false) } } - internal abstract object CreateAndSetAttentionPacket(); + internal abstract PacketHandle CreateAndSetAttentionPacket(); - internal abstract void SetPacketData(object packet, byte[] buffer, int bytesUsed); + internal abstract void SetPacketData(PacketHandle packet, byte[] buffer, int bytesUsed); private Task WriteSni(bool canAccumulate) { // Prepare packet, and write to packet. - object packet = GetResetWritePacket(); + PacketHandle packet = GetResetWritePacket(); SetBufferSecureStrings(); SetPacketData(packet, _outBuff, _outBytesUsed); @@ -3617,7 +3711,7 @@ internal int WarningCount } } - protected abstract object EmptyReadPacket { get; } + protected abstract PacketHandle EmptyReadPacket { get; } /// /// Gets the full list of errors and warnings (including the pre-attention ones), then wipes all error and warning lists diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectManaged.cs index 103e6fb163c5..513a5847dd6f 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -31,14 +31,14 @@ internal TdsParserStateObjectManaged(TdsParser parser, TdsParserStateObject phys internal override uint Status => _sessionHandle != null ? _sessionHandle.Status : TdsEnums.SNI_UNINITIALIZED; - internal override object SessionHandle => _sessionHandle; + internal override SessionHandle SessionHandle => SessionHandle.FromManagedSession(_sessionHandle); - protected override object EmptyReadPacket => null; + protected override PacketHandle EmptyReadPacket => default; - protected override bool CheckPacket(object packet, TaskCompletionSource source) + protected override bool CheckPacket(PacketHandle packet, TaskCompletionSource source) { - SNIPacket p = packet as SNIPacket; - return p.IsInvalid || (!p.IsInvalid && source != null); + SNIPacket p = packet.ManagedPacket; + return p.IsInvalid || source != null; } protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) @@ -54,7 +54,7 @@ internal SNIMarsHandle CreateMarsSession(object callbackObject, bool async) return _marsConnection.CreateMarsSession(callbackObject, async); } - protected override uint SNIPacketGetData(object packet, byte[] _inBuff, ref uint dataSize) => SNIProxy.Singleton.PacketGetData(packet as SNIPacket, _inBuff, ref dataSize); + protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize) => SNIProxy.Singleton.PacketGetData(packet.ManagedPacket, _inBuff, ref dataSize); internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[] spnBuffer, bool flushCache, bool async, bool parallel, bool isIntegratedSecurity) { @@ -72,11 +72,11 @@ internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSni } } - internal void ReadAsyncCallback(SNIPacket packet, uint error) => ReadAsyncCallback(IntPtr.Zero, packet, error); + internal void ReadAsyncCallback(SNIPacket packet, uint error) => ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error); - internal void WriteAsyncCallback(SNIPacket packet, uint sniError) => WriteAsyncCallback(IntPtr.Zero, packet, sniError); + internal void WriteAsyncCallback(SNIPacket packet, uint sniError) => WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError); - protected override void RemovePacketFromPendingList(object packet) + protected override void RemovePacketFromPendingList(PacketHandle packet) { // No-Op } @@ -125,7 +125,7 @@ protected override void FreeGcHandle(int remaining, bool release) internal override bool IsFailedHandle() => _sessionHandle.Status != TdsEnums.SNI_SUCCESS; - internal override object ReadSyncOverAsync(int timeoutRemaining, out uint error) + internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error) { SNIHandle handle = Handle; if (handle == null) @@ -134,17 +134,17 @@ internal override object ReadSyncOverAsync(int timeoutRemaining, out uint error) } SNIPacket packet = null; error = SNIProxy.Singleton.ReadSyncOverAsync(handle, out packet, timeoutRemaining); - return packet; + return PacketHandle.FromManagedPacket(packet); } - internal override bool IsPacketEmpty(object packet) + internal override bool IsPacketEmpty(PacketHandle packet) { - return packet == null; + return packet.ManagedPacket == null; } - internal override void ReleasePacket(object syncReadPacket) + internal override void ReleasePacket(PacketHandle syncReadPacket) { - ((SNIPacket)syncReadPacket).Dispose(); + syncReadPacket.ManagedPacket?.Dispose(); } internal override uint CheckConnection() @@ -153,38 +153,39 @@ internal override uint CheckConnection() return handle == null ? TdsEnums.SNI_SUCCESS : SNIProxy.Singleton.CheckConnection(handle); } - internal override object ReadAsync(out uint error, ref object handle) - { + internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) + { + Debug.Assert(handle.Type == SessionHandle.ManagedHandleType, "unexpected handle type when requiring ManagedHandle"); SNIPacket packet; - error = SNIProxy.Singleton.ReadAsync((SNIHandle)handle, out packet); - return packet; + error = SNIProxy.Singleton.ReadAsync(handle.ManagedHandle, out packet); + return PacketHandle.FromManagedPacket(packet); } - internal override object CreateAndSetAttentionPacket() + internal override PacketHandle CreateAndSetAttentionPacket() { if (_sniAsyncAttnPacket == null) { SNIPacket attnPacket = new SNIPacket(); - SetPacketData(attnPacket, SQL.AttentionHeader, TdsEnums.HEADER_LEN); + SetPacketData(PacketHandle.FromManagedPacket(attnPacket), SQL.AttentionHeader, TdsEnums.HEADER_LEN); _sniAsyncAttnPacket = attnPacket; } - return _sniAsyncAttnPacket; + return PacketHandle.FromManagedPacket(_sniAsyncAttnPacket); } - internal override uint WritePacket(object packet, bool sync) + internal override uint WritePacket(PacketHandle packet, bool sync) { - return SNIProxy.Singleton.WritePacket((SNIHandle)Handle, (SNIPacket)packet, sync); + return SNIProxy.Singleton.WritePacket(Handle, packet.ManagedPacket, sync); } - internal override object AddPacketToPendingList(object packet) + internal override PacketHandle AddPacketToPendingList(PacketHandle packet) { // No-Op return packet; } - internal override bool IsValidPacket(object packetPointer) => (SNIPacket)packetPointer != null && !((SNIPacket)packetPointer).IsInvalid; + internal override bool IsValidPacket(PacketHandle packet) => packet.ManagedPacket?.IsInvalid ?? false; - internal override object GetResetWritePacket() + internal override PacketHandle GetResetWritePacket() { if (_sniPacket != null) { @@ -197,7 +198,7 @@ internal override object GetResetWritePacket() _sniPacket = _writePacketCache.Take(Handle); } } - return _sniPacket; + return PacketHandle.FromManagedPacket(_sniPacket); } internal override void ClearAllWritePackets() @@ -214,7 +215,7 @@ internal override void ClearAllWritePackets() } } - internal override void SetPacketData(object packet, byte[] buffer, int bytesUsed) => SNIProxy.Singleton.PacketSetData((SNIPacket)packet, buffer, bytesUsed); + internal override void SetPacketData(PacketHandle packet, byte[] buffer, int bytesUsed) => SNIProxy.Singleton.PacketSetData(packet.ManagedPacket , buffer, bytesUsed); internal override uint SniGetConnectionId(ref Guid clientConnectionId) => SNIProxy.Singleton.GetConnectionId(Handle, ref clientConnectionId); diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectNative.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectNative.cs index c1fa34bd9c70..9607ccc34f59 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParserStateObjectNative.cs @@ -14,15 +14,15 @@ internal class TdsParserStateObjectNative : TdsParserStateObject { private SNIHandle _sessionHandle = null; // the SNI handle we're to work on - private SNIPacket _sniPacket = null; // Will have to re-vamp this for MARS - internal SNIPacket _sniAsyncAttnPacket = null; // Packet to use to send Attn + private SNIPacketHandle _sniPacket = null; // Will have to re-vamp this for MARS + internal SNIPacketHandle _sniAsyncAttnPacket = null; // Packet to use to send Attn private readonly WritePacketCache _writePacketCache = new WritePacketCache(); // Store write packets that are ready to be re-used public TdsParserStateObjectNative(TdsParser parser) : base(parser) { } private GCHandle _gcHandle; // keeps this object alive until we're closed. - private Dictionary _pendingWritePackets = new Dictionary(); // Stores write packets that have been sent to SNI, but have not yet finished writing (i.e. we are waiting for SNI's callback) + private Dictionary _pendingWritePackets = new Dictionary(); // Stores write packets that have been sent to SNI, but have not yet finished writing (i.e. we are waiting for SNI's callback) internal TdsParserStateObjectNative(TdsParser parser, TdsParserStateObject physicalConnection, bool async) : base(parser, physicalConnection, async) @@ -33,9 +33,9 @@ internal TdsParserStateObjectNative(TdsParser parser, TdsParserStateObject physi internal override uint Status => _sessionHandle != null ? _sessionHandle.Status : TdsEnums.SNI_UNINITIALIZED; - internal override object SessionHandle => _sessionHandle; + internal override SessionHandle SessionHandle => SessionHandle.FromNativeHandle(_sessionHandle); - protected override object EmptyReadPacket => IntPtr.Zero; + protected override PacketHandle EmptyReadPacket => default; protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async) { @@ -97,11 +97,16 @@ internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSni _sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer, ignoreSniOpenTimeout, checked((int)timeout), out instanceName, flushCache, !async, fParallel); } - protected override uint SNIPacketGetData(object packet, byte[] _inBuff, ref uint dataSize) => SNINativeMethodWrapper.SNIPacketGetData((IntPtr)packet, _inBuff, ref dataSize); + protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize) + { + Debug.Assert(packet.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + return SNINativeMethodWrapper.SNIPacketGetData(packet.NativePointer, _inBuff, ref dataSize); + } - protected override bool CheckPacket(object packet, TaskCompletionSource source) + protected override bool CheckPacket(PacketHandle packet, TaskCompletionSource source) { - IntPtr ptr = (IntPtr)(object)packet; + Debug.Assert(packet.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + IntPtr ptr = packet.NativePointer; return IntPtr.Zero == ptr || IntPtr.Zero != ptr && source != null; } @@ -109,11 +114,12 @@ protected override bool CheckPacket(object packet, TaskCompletionSource public void WriteAsyncCallback(IntPtr key, IntPtr packet, uint sniError) => WriteAsyncCallback(key, packet, sniError); - protected override void RemovePacketFromPendingList(object ptr) + protected override void RemovePacketFromPendingList(PacketHandle ptr) { - IntPtr pointer = (IntPtr)ptr; + Debug.Assert(ptr.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + IntPtr pointer = ptr.NativePointer; - SNIPacket recoveredPacket; + SNIPacketHandle recoveredPacket; lock (_writePacketLockObject) { @@ -169,7 +175,7 @@ protected override void FreeGcHandle(int remaining, bool release) internal override bool IsFailedHandle() => _sessionHandle.Status != TdsEnums.SNI_SUCCESS; - internal override object ReadSyncOverAsync(int timeoutRemaining, out uint error) + internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error) { SNIHandle handle = Handle; if (handle == null) @@ -178,12 +184,20 @@ internal override object ReadSyncOverAsync(int timeoutRemaining, out uint error) } IntPtr readPacketPtr = IntPtr.Zero; error = SNINativeMethodWrapper.SNIReadSyncOverAsync(handle, ref readPacketPtr, GetTimeoutRemaining()); - return readPacketPtr; + return PacketHandle.FromNativePointer(readPacketPtr); } - internal override bool IsPacketEmpty(object readPacket) => IntPtr.Zero == (IntPtr)readPacket; + internal override bool IsPacketEmpty(PacketHandle readPacket) + { + Debug.Assert(readPacket.Type == PacketHandle.NativePointerType || readPacket.Type==0 , "unexpected packet type when requiring NativePointer"); + return IntPtr.Zero == readPacket.NativePointer; + } - internal override void ReleasePacket(object syncReadPacket) => SNINativeMethodWrapper.SNIPacketRelease((IntPtr)syncReadPacket); + internal override void ReleasePacket(PacketHandle syncReadPacket) + { + Debug.Assert(syncReadPacket.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + SNINativeMethodWrapper.SNIPacketRelease(syncReadPacket.NativePointer); + } internal override uint CheckConnection() { @@ -191,27 +205,33 @@ internal override uint CheckConnection() return handle == null ? TdsEnums.SNI_SUCCESS : SNINativeMethodWrapper.SNICheckConnection(handle); } - internal override object ReadAsync(out uint error, ref object handle) - { + internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) + { + Debug.Assert(handle.Type == SessionHandle.NativeHandleType, "unexpected handle type when requiring NativePointer"); IntPtr readPacketPtr = IntPtr.Zero; - error = SNINativeMethodWrapper.SNIReadAsync((SNIHandle)handle, ref readPacketPtr); - return readPacketPtr; + error = SNINativeMethodWrapper.SNIReadAsync(handle.NativeHandle, ref readPacketPtr); + return PacketHandle.FromNativePointer(readPacketPtr); } - internal override object CreateAndSetAttentionPacket() + internal override PacketHandle CreateAndSetAttentionPacket() { SNIHandle handle = Handle; - SNIPacket attnPacket = new SNIPacket(handle); + SNIPacketHandle attnPacket = new SNIPacketHandle(handle); _sniAsyncAttnPacket = attnPacket; - SetPacketData(attnPacket, SQL.AttentionHeader, TdsEnums.HEADER_LEN); - return attnPacket; + SetPacketData(PacketHandle.FromNativePacket(attnPacket), SQL.AttentionHeader, TdsEnums.HEADER_LEN); + return PacketHandle.FromNativePacket(attnPacket); } - internal override uint WritePacket(object packet, bool sync) => SNINativeMethodWrapper.SNIWritePacket(Handle, (SNIPacket)packet, sync); + internal override uint WritePacket(PacketHandle packet, bool sync) + { + Debug.Assert(packet.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePacket"); + return SNINativeMethodWrapper.SNIWritePacket(Handle, packet.NativePacket, sync); + } - internal override object AddPacketToPendingList(object packetToAdd) + internal override PacketHandle AddPacketToPendingList(PacketHandle packetToAdd) { - SNIPacket packet = (SNIPacket)packetToAdd; + Debug.Assert(packetToAdd.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePacket"); + SNIPacketHandle packet = packetToAdd.NativePacket; Debug.Assert(packet == _sniPacket, "Adding a packet other than the current packet to the pending list"); _sniPacket = null; IntPtr pointer = packet.DangerousGetHandle(); @@ -221,12 +241,16 @@ internal override object AddPacketToPendingList(object packetToAdd) _pendingWritePackets.Add(pointer, packet); } - return pointer; + return PacketHandle.FromNativePointer(pointer); } - internal override bool IsValidPacket(object packetPointer) => (IntPtr)packetPointer != IntPtr.Zero; + internal override bool IsValidPacket(PacketHandle packetPointer) + { + Debug.Assert(packetPointer.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer"); + return packetPointer.NativePointer != IntPtr.Zero; + } - internal override object GetResetWritePacket() + internal override PacketHandle GetResetWritePacket() { if (_sniPacket != null) { @@ -239,7 +263,7 @@ internal override object GetResetWritePacket() _sniPacket = _writePacketCache.Take(Handle); } } - return _sniPacket; + return PacketHandle.FromNativePacket(_sniPacket); } internal override void ClearAllWritePackets() @@ -256,8 +280,11 @@ internal override void ClearAllWritePackets() } } - internal override void SetPacketData(object packet, byte[] buffer, int bytesUsed) - => SNINativeMethodWrapper.SNIPacketSetData((SNIPacket)packet, buffer, bytesUsed); + internal override void SetPacketData(PacketHandle packet, byte[] buffer, int bytesUsed) + { + Debug.Assert(packet.Type == PacketHandle.NativePacketType, "unexpected packet type when requiring NativePacket"); + SNINativeMethodWrapper.SNIPacketSetData(packet.NativePacket, buffer, bytesUsed); + } internal override uint SniGetConnectionId(ref Guid clientConnectionId) => SNINativeMethodWrapper.SniGetConnectionId(Handle, ref clientConnectionId); @@ -296,17 +323,17 @@ internal override void DisposePacketCache() internal sealed class WritePacketCache : IDisposable { private bool _disposed; - private Stack _packets; + private Stack _packets; public WritePacketCache() { _disposed = false; - _packets = new Stack(); + _packets = new Stack(); } - public SNIPacket Take(SNIHandle sniHandle) + public SNIPacketHandle Take(SNIHandle sniHandle) { - SNIPacket packet; + SNIPacketHandle packet; if (_packets.Count > 0) { // Success - reset the packet @@ -316,12 +343,12 @@ public SNIPacket Take(SNIHandle sniHandle) else { // Failed to take a packet - create a new one - packet = new SNIPacket(sniHandle); + packet = new SNIPacketHandle(sniHandle); } return packet; } - public void Add(SNIPacket packet) + public void Add(SNIPacketHandle packet) { if (!_disposed) { diff --git a/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckDatabaseIsPresentFactAttribute.cs b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckDatabaseIsPresentFactAttribute.cs new file mode 100644 index 000000000000..869721768330 --- /dev/null +++ b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckDatabaseIsPresentFactAttribute.cs @@ -0,0 +1,28 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Data.SqlClient.ManualTesting.Tests +{ + public class CheckDatabaseIsPresentFactAttribute : FactAttribute + { + public CheckDatabaseIsPresentFactAttribute(string name) + { + if (!DataTestUtility.AreConnStringsSetup()) + { + Skip = "Connection Strings Not Setup"; + } + else if (!DataTestUtility.IsDatabasePresent(name)) + { + Skip = $@"Database ""{name}"" Is Not Present"; + } + } + } +} diff --git a/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckServiceBrokerEnabledFactAttribute.cs b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckServiceBrokerEnabledFactAttribute.cs new file mode 100644 index 000000000000..88681a7b2829 --- /dev/null +++ b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/CheckServiceBrokerEnabledFactAttribute.cs @@ -0,0 +1,28 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace System.Data.SqlClient.ManualTesting.Tests +{ + public class CheckServiceBrokerEnabledFactAttribute : FactAttribute + { + public CheckServiceBrokerEnabledFactAttribute() + { + if (!DataTestUtility.AreConnStringsSetup()) + { + Skip = "Connection Strings Not Setup"; + } + else if (!DataTestUtility.IsServiceBrokerEnabled()) + { + Skip = "Service Broker Not Enabled"; + } + } + } +} diff --git a/src/System.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index f1160fbb1177..be73ff854e61 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -2,6 +2,7 @@ // 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.Collections.Generic; using System.Globalization; using System.Reflection; using System.Threading.Tasks; @@ -13,6 +14,7 @@ public static class DataTestUtility { public static readonly string NpConnStr = null; public static readonly string TcpConnStr = null; + private static readonly Assembly s_systemDotData = typeof(System.Data.SqlClient.SqlConnection).GetTypeInfo().Assembly; private static readonly Type s_tdsParserStateObjectFactory = s_systemDotData?.GetType("System.Data.SqlClient.TdsParserStateObjectFactory"); private static readonly PropertyInfo s_useManagedSNI = s_tdsParserStateObjectFactory?.GetProperty("UseManagedSNI", BindingFlags.Static | BindingFlags.Public); @@ -21,6 +23,10 @@ public static class DataTestUtility ".database.cloudapi.de", ".database.usgovcloudapi.net", ".database.chinacloudapi.cn"}; + + private static bool? serviceBrokerEnabled; + private static Dictionary databasesAvailable; + static DataTestUtility() { NpConnStr = Environment.GetEnvironmentVariable("TEST_NP_CONN_STR"); @@ -32,6 +38,68 @@ public static bool AreConnStringsSetup() return !string.IsNullOrEmpty(NpConnStr) && !string.IsNullOrEmpty(TcpConnStr); } + public static bool IsServiceBrokerEnabled() + { + if (!serviceBrokerEnabled.HasValue) + { + serviceBrokerEnabled = false; + if (AreConnStringsSetup()) + { + try + { + var builder = new SqlConnectionStringBuilder(TcpConnStr); + string database = builder.InitialCatalog; + builder.ConnectTimeout = 2; + using (var connection = new SqlConnection(builder.ToString())) + using (var command = new SqlCommand("SELECT is_service_broker_enabled FROM sys.sys.databases WHERE name=@name", connection)) + { + command.Parameters.AddWithValue("name", database); + using (var reader = command.ExecuteReader()) + { + if (reader.HasRows && reader.Read()) + { + serviceBrokerEnabled = (reader.GetInt32(0) == 1); + } + } + } + } + catch (Exception) + { + serviceBrokerEnabled = false; + } + } + } + return serviceBrokerEnabled.Value; + } + + public static bool IsDatabasePresent(string name) + { + if (databasesAvailable == null) + { + databasesAvailable = new Dictionary(); + } + bool present = false; + if (AreConnStringsSetup() && !string.IsNullOrEmpty(name) && !databasesAvailable.TryGetValue(name, out present)) + { + try + { + var builder = new SqlConnectionStringBuilder(TcpConnStr); + builder.ConnectTimeout = 2; + using (var connection = new SqlConnection(builder.ToString())) + using (var command = new SqlCommand("SELECT COUNT(*) FROM sys.sys.databases WHERE name=@name", connection)) + { + command.Parameters.AddWithValue("name", name); + present = Convert.ToInt32(command.ExecuteScalar()) == 1; + } + } + catch (Exception) + { + } + databasesAvailable[name] = present; + } + return present; + } + public static bool IsUsingManagedSNI() => (bool)(s_useManagedSNI?.GetValue(null) ?? false); // the name length will be no more then (16 + prefix.Length + escapeLeft.Length + escapeRight.Length) diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/SqlNotificationTest/SqlNotificationTest.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/SqlNotificationTest/SqlNotificationTest.cs index 1c8a3d2783fc..12945545299d 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/SqlNotificationTest/SqlNotificationTest.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/SqlNotificationTest/SqlNotificationTest.cs @@ -39,7 +39,7 @@ public void Dispose() #region StartStop_Tests - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_DoubleStart_SameConnStr() { Assert.True(SqlDependency.Start(_startConnectionString), "Failed to start listener."); @@ -51,7 +51,7 @@ public void Test_DoubleStart_SameConnStr() Assert.True(SqlDependency.Stop(_startConnectionString), "Failed to stop listener."); } - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_DoubleStart_DifferentConnStr() { SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(_startConnectionString); @@ -76,7 +76,7 @@ public void Test_DoubleStart_DifferentConnStr() } } - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_Start_DifferentDB() { SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(_startConnectionString) @@ -97,7 +97,7 @@ public void Test_Start_DifferentDB() #region SqlDependency_Tests - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_SingleDependency_NoStart() { using (SqlConnection conn = new SqlConnection(_execConnectionString)) @@ -115,7 +115,7 @@ public void Test_SingleDependency_NoStart() } } - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_SingleDependency_Stopped() { SqlDependency.Start(_startConnectionString); @@ -137,7 +137,7 @@ public void Test_SingleDependency_Stopped() } } - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_SingleDependency_AllDefaults_SqlAuth() { Assert.True(SqlDependency.Start(_startConnectionString), "Failed to start listener."); @@ -181,7 +181,7 @@ public void Test_SingleDependency_AllDefaults_SqlAuth() } } - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_SingleDependency_CustomQueue_SqlAuth() { Assert.True(SqlDependency.Start(_startConnectionString, _queueName), "Failed to start listener."); @@ -225,7 +225,7 @@ public void Test_SingleDependency_CustomQueue_SqlAuth() /// /// SqlDependecy premature timeout /// - [CheckConnStrSetupFact] + [CheckServiceBrokerEnabledFact] public void Test_SingleDependency_Timeout() { Assert.True(SqlDependency.Start(_startConnectionString), "Failed to start listener."); diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtBulkCopyTest.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtBulkCopyTest.cs index 083652810aae..7fe151ec4f37 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtBulkCopyTest.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtBulkCopyTest.cs @@ -6,12 +6,13 @@ namespace System.Data.SqlClient.ManualTesting.Tests { public class UdtBulkCopyTest { + private const string UdtTestDbName = "UdtTestDb"; private string _connStr; - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void RunCopyTest() { - _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = "UdtTestDb" }).ConnectionString; + _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = UdtTestDbName }).ConnectionString; SqlConnection conn = new SqlConnection(_connStr); string cities = DataTestUtility.GetUniqueNameForSqlServer("UdtBulkCopy_cities"); diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest.cs index 100d6b2d0e6c..c9d98eb3e549 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest.cs @@ -10,14 +10,15 @@ namespace System.Data.SqlClient.ManualTesting.Tests { public class UdtTest { + private const string UdtTestDbName = "UdtTestDb"; private string _connStr; public UdtTest() { - _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = "UdtTestDb" }).ConnectionString; + _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = UdtTestDbName }).ConnectionString; } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void ReaderTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -57,7 +58,7 @@ public void ReaderTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void ExecuteScalarTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -74,7 +75,7 @@ public void ExecuteScalarTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void InputParameterTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -123,7 +124,7 @@ public void InputParameterTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void OutputParameterTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -158,7 +159,7 @@ public void OutputParameterTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void FillTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -180,7 +181,7 @@ public void FillTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UpdateTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -216,7 +217,7 @@ public void UpdateTest() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void NullTest() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -290,4 +291,4 @@ private void VerifyDataSet(DataSet ds, Utf8String[] expectedValues) } } } -} \ No newline at end of file +} diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest2.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest2.cs index 1d3274f1922c..1799ac4b1ae0 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest2.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest2.cs @@ -11,14 +11,15 @@ namespace System.Data.SqlClient.ManualTesting.Tests { public class UdtTest2 { + private const string UdtTestDbName = "UdtTestDb"; private string _connStr = null; public UdtTest2() { - _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = "UdtTestDb" }).ConnectionString; + _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { InitialCatalog = UdtTestDbName }).ConnectionString; } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_Early() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -48,7 +49,7 @@ public void UDTParams_Early() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_Binary() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -77,7 +78,7 @@ public void UDTParams_Binary() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_Invalid2() { string spInsertCustomer = DataTestUtility.GetUniqueNameForSqlServer("spUdtTest2_InsertCustomer"); @@ -117,7 +118,7 @@ public void UDTParams_Invalid2() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_Invalid() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -136,7 +137,7 @@ public void UDTParams_Invalid() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_TypedNull() { string spInsertCustomer = DataTestUtility.GetUniqueNameForSqlServer("spUdtTest2_InsertCustomer"); @@ -181,7 +182,7 @@ public void UDTParams_TypedNull() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_NullInput() { string spInsertCustomer = DataTestUtility.GetUniqueNameForSqlServer("spUdtTest2_InsertCustomer"); @@ -225,7 +226,7 @@ public void UDTParams_NullInput() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTParams_InputOutput() { string spInsertCity = DataTestUtility.GetUniqueNameForSqlServer("spUdtTest2_InsertCity"); @@ -287,7 +288,7 @@ public void UDTParams_InputOutput() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDTFields_WrongType() { using (SqlConnection cn = new SqlConnection(_connStr)) @@ -317,7 +318,7 @@ public void UDTFields_WrongType() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void UDT_DataSetFill() { using (SqlConnection cn = new SqlConnection(_connStr)) @@ -341,7 +342,7 @@ public void UDT_DataSetFill() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void Reader_PointEarly() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -375,7 +376,7 @@ public void Reader_PointEarly() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void Reader_LineEarly() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -435,7 +436,7 @@ public void Reader_LineEarly() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void Reader_PointLate() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -468,7 +469,7 @@ public void Reader_PointLate() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void Reader_CircleLate() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -500,7 +501,7 @@ public void Reader_CircleLate() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void TestSchemaTable() { using (SqlConnection conn = new SqlConnection(_connStr)) @@ -562,7 +563,7 @@ public void TestSchemaTable() } } - [CheckConnStrSetupFact] + [CheckDatabaseIsPresentFact(UdtTestDbName)] public void TestSqlUserDefinedAggregateAttributeMaxByteSize() { Func create diff --git a/src/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj b/src/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj index 5dec364ce30d..dae2e15ac783 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj @@ -8,6 +8,8 @@ Common\System\Collections\DictionaryExtensions.cs + +