diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 781f360991..a9cd43be97 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -3144,7 +3144,7 @@ internal void ReadSni(TaskCompletionSource completion) // the identity source. The identity value is used to correlate timer callback events to the currently // running timeout and prevents a late timer callback affecting a result it does not relate to int previousTimeoutState = Interlocked.CompareExchange(ref _timeoutState, TimeoutState.Running, TimeoutState.Stopped); - Debug.Assert(previousTimeoutState == TimeoutState.Stopped, "previous timeout state was not Stopped"); + if (previousTimeoutState == TimeoutState.Stopped) { Debug.Assert(_timeoutIdentityValue == 0, "timer was previously stopped without resetting the _identityValue"); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index b3f90cd34e..b82b1fec0e 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -595,10 +595,21 @@ public static string GetUniqueNameForSqlServer(string prefix, bool withBracket = Environment.MachineName, DateTime.Now.ToString("yyyy_MM_dd", CultureInfo.InvariantCulture)); string name = GetUniqueName(extendedPrefix, withBracket); - if (name.Length > 128) + + // Truncate to no more than 128 characters. + const int maxLen = 128; + if (name.Length > maxLen) { - throw new ArgumentOutOfRangeException("the name is too long - SQL Server names are limited to 128"); + if (withBracket) + { + name = name.Substring(0, maxLen - 1) + ']'; + } + else + { + name = name.Substring(0, maxLen); + } } + return name; } 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 7bd503c5b9..5464b5c504 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 @@ -79,7 +79,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTest.cs deleted file mode 100644 index 8208f7e496..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTest.cs +++ /dev/null @@ -1,106 +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.Diagnostics; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.Data.SqlClient.ManualTesting.Tests -{ - public static class AsyncTest - { - [ActiveIssue("5533")] // Async Operations slower than Sync operations - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] - public static void TestReadAsyncTimeConsumed() - { - const string sql = "SET NOCOUNT ON" - + " SELECT 'a'" - + " DECLARE @t DATETIME = SYSDATETIME()" - + " WHILE DATEDIFF(s, @t, SYSDATETIME()) < 20 BEGIN" - + " SELECT 2 x INTO #y" - + " DROP TABLE #y" - + " END" - + " SELECT 'b'"; - Task t = RunReadAsync(sql); - double elapsedSync = RunReadSync(sql); - t.Wait(); - double elapsedAsync = t.Result; - Assert.True(elapsedAsync < elapsedSync, "Asynchronous operation should be finished quicker than synchronous one"); - int limit = 100; - Assert.True(elapsedAsync < limit, $"Asynchronous operation should be finished within {limit}ms"); - } - - private static async Task RunReadAsync(string sql) - { - double maxElapsedTimeMillisecond = 0; - using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) - { - await connection.OpenAsync(); - using (SqlCommand command = connection.CreateCommand()) - { - command.CommandText = sql; - using (SqlDataReader reader = await command.ExecuteReaderAsync()) - { - Task t; - Stopwatch stopwatch = new Stopwatch(); - do - { - do - { - stopwatch.Start(); - t = reader.ReadAsync(); - stopwatch.Stop(); - double elased = stopwatch.Elapsed.TotalMilliseconds; - if (maxElapsedTimeMillisecond < elased) - { - maxElapsedTimeMillisecond = elased; - } - } - while (await t); - } - while (reader.NextResult()); - } - } - } - - return maxElapsedTimeMillisecond; - } - - private static double RunReadSync(string sql) - { - double maxElapsedTimeMillisecond = 0; - using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) - { - connection.Open(); - using (SqlCommand command = connection.CreateCommand()) - { - command.CommandText = sql; - using (SqlDataReader reader = command.ExecuteReader()) - { - bool result; - Stopwatch stopwatch = new Stopwatch(); - do - { - do - { - stopwatch.Start(); - result = reader.Read(); - stopwatch.Stop(); - double elased = stopwatch.Elapsed.TotalMilliseconds; - if (maxElapsedTimeMillisecond < elased) - { - maxElapsedTimeMillisecond = elased; - } - } - while (result); - } - while (reader.NextResult()); - } - } - } - - return maxElapsedTimeMillisecond; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs index ee9c0ed4cb..9924c6d104 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; +using System.Collections.Generic; using System.Data; using System.Data.SqlTypes; using System.IO; @@ -12,6 +13,7 @@ using System.Threading; using System.Threading.Tasks; using System.Xml; +using Microsoft.Data.SqlClient.TestUtilities; using Xunit; namespace Microsoft.Data.SqlClient.ManualTesting.Tests @@ -21,6 +23,7 @@ public static class DataStreamTest [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))] public static void RunAllTestsForSingleServer_NP() { + // @TODO: Split into separate tests! Or why even bother running this test on non-windows, the error comes from something other than data stream! if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { DataTestUtility.AssertThrowsWrapper(() => RunAllTestsForSingleServer(DataTestUtility.NPConnectionString, true)); @@ -30,8 +33,7 @@ public static void RunAllTestsForSingleServer_NP() RunAllTestsForSingleServer(DataTestUtility.NPConnectionString, true); } } - - [ActiveIssue("5540")] + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void RunAllTestsForSingleServer_TCP() { @@ -152,6 +154,7 @@ IF OBJECT_ID('dbo.{tableName}', 'U') IS NOT NULL return data; } + // @TODO: Split into separate tests! private static void RunAllTestsForSingleServer(string connectionString, bool usingNamePipes = false) { RowBuffer(connectionString); @@ -178,16 +181,23 @@ private static void RunAllTestsForSingleServer(string connectionString, bool usi ReadTextReader(connectionString); StreamingBlobDataTypes(connectionString); OutOfOrderGetChars(connectionString); - TestXEventsStreaming(connectionString); - // These tests fail with named pipes, since they try to do DNS lookups on named pipe paths. - if (!usingNamePipes) + // These tests fail on Azure or Named Instances, so skip them for + // those contexts. + var dataSource = new SqlConnectionStringBuilder(connectionString).DataSource; + if (!Utils.IsAzureSqlServer(dataSource) + && !dataSource.Contains(@"\")) { - if (DataTestUtility.IsUsingNativeSNI()) + TestXEventsStreaming(connectionString); + + // These tests also fail with named pipes, since they try to do + // DNS lookups on named pipe paths. + // + // They also are only meant to run for native SNI. + if (!usingNamePipes && DataTestUtility.IsUsingNativeSNI()) { TimeoutDuringReadAsyncWithClosedReaderTest(connectionString); } - NonFatalTimeoutDuringRead(connectionString); } } @@ -697,7 +707,7 @@ private static void ExecuteXmlReaderTest(string connectionString) "", }; - xr.Read(); + Assert.True(xr.Read()); for (int i = 0; !xr.EOF; i++) { Assert.True(i < expectedResults.Length, "ERROR: Received more XML results than expected"); @@ -712,7 +722,7 @@ private static void ExecuteXmlReaderTest(string connectionString) string errorMessage; using (xr = cmd.ExecuteXmlReader()) { - xr.Read(); + Assert.True(xr.Read()); // make sure we get an exception if we try to get another reader errorMessage = SystemDataResourceManager.Instance.ADP_OpenReaderExists("Connection"); @@ -723,7 +733,7 @@ private static void ExecuteXmlReaderTest(string connectionString) cmd.CommandText = "select * from orders for xml auto"; using (xr = cmd.ExecuteXmlReader()) { - xr.Read(); + Assert.True(xr.Read()); conn.Close(); conn.Open(); } @@ -732,7 +742,7 @@ private static void ExecuteXmlReaderTest(string connectionString) cmd.CommandText = "select * from orders for xml auto"; using (xr = cmd.ExecuteXmlReader()) { - xr.Read(); + Assert.True(xr.Read()); while (!xr.EOF) { xr.ReadOuterXml(); @@ -743,11 +753,8 @@ private static void ExecuteXmlReaderTest(string connectionString) cmd.CommandText = "select * from orders where 0 = 1 for xml auto"; using (xr = cmd.ExecuteXmlReader()) { - xr.Read(); - while (!xr.EOF) - { - xr.ReadOuterXml(); - } + Assert.False(xr.Read()); + Assert.True(xr.EOF); } // multiple results @@ -757,7 +764,10 @@ private static void ExecuteXmlReaderTest(string connectionString) "select employeeId from employees where employeeid < 3 for xml auto;"; using (xr = cmd.ExecuteXmlReader()) { - string[] expectedResults = + // The XML elements may be returned in any order, so we + // must use a set to track which expected elements we've + // seen. + var expectedResults = new HashSet { "", "", @@ -769,14 +779,25 @@ private static void ExecuteXmlReaderTest(string connectionString) "", "" }; - xr.Read(); - for (int i = 0; !xr.EOF; i++) + + Assert.True(xr.Read()); + + // Read all of the rows. + while (! xr.EOF) { - Assert.True(i < expectedResults.Length, "ERROR: Received more XML results than expected"); + // We have a row, so we must have at least one + // expected element to check. + Assert.NotEmpty(expectedResults); + // Obtain the current row's XML element. string actualResult = xr.ReadOuterXml(); - DataTestUtility.AssertEqualsWithDescription(expectedResults[i], actualResult, "FAILED: Actual XML results differed from expected value."); + + // We must find the current row in our expected set. + Assert.True(expectedResults.Remove(actualResult)); } + + // We must have seen all expected elements. + Assert.Empty(expectedResults); } // multiple columns @@ -1281,7 +1302,7 @@ private static void GetStream(string connectionString) Assert.False(t.Wait(1), "FAILED: Read completed immediately"); DataTestUtility.AssertThrowsWrapper(() => reader.GetStream(8)); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); // GetStream after Read DataTestUtility.AssertThrowsWrapper(() => reader.GetStream(0)); @@ -1319,7 +1340,7 @@ private static void GetStream(string connectionString) Assert.True(t.IsCompleted, "FAILED: Failed to get stream within 1 second"); t = reader.ReadAsync(); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); } #endif } @@ -1393,7 +1414,7 @@ private static void GetTextReader(string connectionString) Assert.False(t.IsCompleted, "FAILED: Read completed immediately"); DataTestUtility.AssertThrowsWrapper(() => reader.GetTextReader(8)); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); // GetTextReader after Read DataTestUtility.AssertThrowsWrapper(() => reader.GetTextReader(0)); @@ -1432,7 +1453,7 @@ private static void GetTextReader(string connectionString) Assert.True(t.IsCompleted, "FAILED: Failed to get TextReader within 1 second"); t = reader.ReadAsync(); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); } #endif } @@ -1483,7 +1504,7 @@ private static void GetXmlReader(string connectionString) Assert.False(t.IsCompleted, "FAILED: Read completed immediately"); DataTestUtility.AssertThrowsWrapper(() => reader.GetXmlReader(6)); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); // GetXmlReader after Read DataTestUtility.AssertThrowsWrapper(() => reader.GetXmlReader(0)); @@ -1609,7 +1630,7 @@ private static void ReadStream(string connectionString) DataTestUtility.AssertThrowsWrapper(() => { _ = stream.Read(largeBuffer, 0, largeBuffer.Length); }); DataTestUtility.AssertThrowsWrapper(() => reader.Read()); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); } using (SqlDataReader reader = cmd.ExecuteReader(behavior)) { @@ -1768,7 +1789,7 @@ private static void ReadTextReader(string connectionString) DataTestUtility.AssertThrowsWrapper(() => textReader.Read(largeBuffer, 0, largeBuffer.Length)); DataTestUtility.AssertThrowsWrapper(() => reader.Read()); } - t.Wait(); + DataTestUtility.AssertThrowsWrapper(() => t.Wait()); } using (SqlDataReader reader = cmd.ExecuteReader(behavior)) @@ -2002,48 +2023,6 @@ private static void TimeoutDuringReadAsyncWithClosedReaderTest(string connection } } - private static void NonFatalTimeoutDuringRead(string connectionString) - { - // Create the proxy - ProxyServer proxy = ProxyServer.CreateAndStartProxy(connectionString, out connectionString); - proxy.SimulatedPacketDelay = 100; - proxy.SimulatedOutDelay = true; - try - { - using (SqlConnection conn = new SqlConnection(connectionString)) - { - // Start the command - conn.Open(); - using (SqlCommand cmd = new SqlCommand("SELECT @p, @p, @p, @p, @p", conn)) - { - cmd.CommandTimeout = 1; - cmd.Parameters.AddWithValue("p", new string('a', 3000)); - using (SqlDataReader reader = cmd.ExecuteReader()) - { - // Slow down packets and wait on ReadAsync - proxy.SimulatedPacketDelay = 1500; - reader.ReadAsync().Wait(); - - // Allow proxy to copy at full speed again - proxy.SimulatedOutDelay = false; - reader.SetDefaultTimeout(30000); - - // Close will now observe the stored timeout error - string errorMessage = SystemDataResourceManager.Instance.SQL_Timeout_Execution; - DataTestUtility.AssertThrowsWrapper(reader.Dispose, errorMessage); - } - } - } - proxy.Stop(); - } - catch - { - // In case of error, stop the proxy and dump its logs (hopefully this will help with debugging - proxy.Stop(); - throw; - } - } - internal static void VerifySchema(SqlDataReader reader) { string[] expectedColNames =