From 43f0be12dc77c4498e026981903df4f761947219 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:17:47 +0000 Subject: [PATCH 1/7] Split MultipleResultsTest, clean up console logging --- .../FunctionalTests/AADAuthenticationTests.cs | 1 - .../FunctionalTests/TestRoutingTdsServer.cs | 2 +- .../tests/FunctionalTests/TestTdsServer.cs | 2 +- ....Data.SqlClient.ManualTesting.Tests.csproj | 5 - .../MultipleResultsTest.bsl | 47 -- .../MultipleResultsTest.cs | 462 +++++------------- .../ManualTests/SQL/ParameterTest/TvpTest.cs | 21 - .../ManualTests/TracingTests/TestTdsServer.cs | 2 +- .../TDS.Servers/TransientFaultTDSServer.cs | 2 +- 9 files changed, 129 insertions(+), 415 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.bsl diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs index 18997a4d86..43e0be9101 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs @@ -76,7 +76,6 @@ public void CustomActiveDirectoryProviderTest_AppClientId_DeviceFlowCallback() private Task CustomDeviceFlowCallback(DeviceCodeResult result) { - Console.WriteLine(result.Message); return Task.FromResult(0); } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestRoutingTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestRoutingTdsServer.cs index 275cb58035..130b50cad9 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestRoutingTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestRoutingTdsServer.cs @@ -42,7 +42,7 @@ public static TestRoutingTdsServer StartTestServer(IPEndPoint destinationEndpoin server._endpoint = new TDSServerEndPoint(server) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. - server._endpoint.EventLog = Console.Out; + server._endpoint.EventLog = enableLog ? Console.Out : null; server._endpoint.Start(); int port = server._endpoint.ServerEndPoint.Port; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs index e383ac4dc6..3b6b816cbc 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs @@ -45,7 +45,7 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool server._endpoint = new TDSServerEndPoint(server) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. - server._endpoint.EventLog = Console.Out; + server._endpoint.EventLog = enableLog ? Console.Out : null; server._endpoint.Start(); int port = server._endpoint.ServerEndPoint.Port; 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 a5b217f1cd..c27914d482 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 @@ -243,11 +243,6 @@ PreserveNewest data.xml - - PreserveNewest - MultipleResultsTest.bsl - - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.bsl b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.bsl deleted file mode 100644 index 99bde8b2c0..0000000000 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.bsl +++ /dev/null @@ -1,47 +0,0 @@ -MultipleErrorHandling SqlConnection -**** ExecuteNonQuery ***** -SqlException: Error 1 -Error 2 -Error 3 -Error 4 -Error 5 -0 -1 -3 -4 -5 -6 -7 -8 -9 -10 -11 -**** ExecuteScalar **** -*** SQL CONNECTION INFO MESSAGE : 0 **** -**** ExecuteReader **** -*** SQL CONNECTION INFO MESSAGE : 0 **** -NextResult -*** SQL CONNECTION INFO MESSAGE : 1 **** -SqlException: Error 1 -NextResult -*** SQL CONNECTION INFO MESSAGE : 3 **** -NextResult -*** SQL CONNECTION INFO MESSAGE : 4 **** -SqlException: Error 2 -NextResult -*** SQL CONNECTION INFO MESSAGE : 5 **** -NextResult -*** SQL CONNECTION INFO MESSAGE : 6 **** -SqlException: Error 3 -NextResult -*** SQL CONNECTION INFO MESSAGE : 7 **** -NextResult -*** SQL CONNECTION INFO MESSAGE : 8 **** -SqlException: Error 4 -NextResult -*** SQL CONNECTION INFO MESSAGE : 9 **** -NextResult -*** SQL CONNECTION INFO MESSAGE : 10 **** -SqlException: Error 5 -NextResult -*** SQL CONNECTION INFO MESSAGE : 11 **** diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs index cc5d6b42c2..a654fec8ed 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs @@ -2,366 +2,154 @@ // 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.Common; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; +using System.Collections.Concurrent; using Xunit; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class MultipleResultsTest { - private StringBuilder _globalBuilder = new StringBuilder(); - private StringBuilder _outputBuilder; - private string[] _outputFilter; + private const string ResultSet1_Message = "0"; + private const string ResultSet2_Message = "1"; + private const string ResultSet2_Error = "Error 1"; + + private const string ResultSet3_Message = "3"; + private const string ResultSet4_Message = "4"; + private const string ResultSet4_Error = "Error 2"; + + private const string ResultSet5_Message = "5"; + private const string ResultSet6_Message = "6"; + private const string ResultSet6_Error = "Error 3"; + + private const string ResultSet7_Message = "7"; + private const string ResultSet8_Message = "8"; + private const string ResultSet8_Error = "Error 4"; + + private const string ResultSet9_Message = "9"; + private const string ResultSet10_Message = "10"; + private const string ResultSet10_Error = "Error 5"; + + private const string ResultSet11_Message = "11"; + + private readonly static string s_sqlStatement = + $"PRINT N'{ResultSet1_Message}'; SELECT num = 1, str = 'ABC';\n" + + $"PRINT N'{ResultSet2_Message}'; RAISERROR('{ResultSet2_Error}', 15, 1);\n" + + $"PRINT N'{ResultSet3_Message}'; SELECT num = 2, str = 'ABC';\n" + + $"PRINT N'{ResultSet4_Message}'; RAISERROR('{ResultSet4_Error}', 15, 1);\n" + + $"PRINT N'{ResultSet5_Message}'; SELECT num = 3, str = 'ABC';\n" + + $"PRINT N'{ResultSet6_Message}'; RAISERROR('{ResultSet6_Error}', 15, 1);\n" + + $"PRINT N'{ResultSet7_Message}'; SELECT num = 4, str = 'ABC';\n" + + $"PRINT N'{ResultSet8_Message}'; RAISERROR('{ResultSet8_Error}', 15, 1);\n" + + $"PRINT N'{ResultSet9_Message}'; SELECT num = 5, str = 'ABC';\n" + + $"PRINT N'{ResultSet10_Message}'; RAISERROR('{ResultSet10_Error}', 15, 1);\n" + + $"PRINT N'{ResultSet11_Message}';"; [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] - public void TestMain() + public void ExecuteNonQuery() { - Assert.True(RunTestCoreAndCompareWithBaseline()); - } + using SqlConnection connection = new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MultipleActiveResultSets = true }).ConnectionString); + using SqlCommand command = connection.CreateCommand(); + ConcurrentQueue messages = new ConcurrentQueue(); - private void RunTest() - { - MultipleErrorHandling(new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MultipleActiveResultSets = true }).ConnectionString)); - } + connection.InfoMessage += (object sender, SqlInfoMessageEventArgs args) => + messages.Enqueue(args.Message); - private void MultipleErrorHandling(DbConnection connection) - { - try - { - Console.WriteLine("MultipleErrorHandling {0}", connection.GetType().Name); - Type expectedException = null; - if (connection is SqlConnection) - { - ((SqlConnection)connection).InfoMessage += delegate (object sender, SqlInfoMessageEventArgs args) - { - Console.WriteLine("*** SQL CONNECTION INFO MESSAGE : {0} ****", args.Message); - }; - expectedException = typeof(SqlException); - } - connection.Open(); - - using (DbCommand command = connection.CreateCommand()) - { - command.CommandText = - "PRINT N'0';\n" + - "SELECT num = 1, str = 'ABC';\n" + - "PRINT N'1';\n" + - "RAISERROR('Error 1', 15, 1);\n" + - "PRINT N'3';\n" + - "SELECT num = 2, str = 'ABC';\n" + - "PRINT N'4';\n" + - "RAISERROR('Error 2', 15, 1);\n" + - "PRINT N'5';\n" + - "SELECT num = 3, str = 'ABC';\n" + - "PRINT N'6';\n" + - "RAISERROR('Error 3', 15, 1);\n" + - "PRINT N'7';\n" + - "SELECT num = 4, str = 'ABC';\n" + - "PRINT N'8';\n" + - "RAISERROR('Error 4', 15, 1);\n" + - "PRINT N'9';\n" + - "SELECT num = 5, str = 'ABC';\n" + - "PRINT N'10';\n" + - "RAISERROR('Error 5', 15, 1);\n" + - "PRINT N'11';\n"; - - try - { - Console.WriteLine("**** ExecuteNonQuery *****"); - command.ExecuteNonQuery(); - } - catch (Exception e) - { - PrintException(expectedException, e); - } - - try - { - Console.WriteLine("**** ExecuteScalar ****"); - command.ExecuteScalar(); - } - catch (Exception e) - { - PrintException(expectedException, e); - } - - try - { - Console.WriteLine("**** ExecuteReader ****"); - using (DbDataReader reader = command.ExecuteReader()) - { - bool moreResults = true; - do - { - try - { - Console.WriteLine("NextResult"); - moreResults = reader.NextResult(); - } - catch (Exception e) - { - PrintException(expectedException, e); - } - } while (moreResults); - } - } - catch (Exception e) - { - PrintException(null, e); - } - } - } - catch (Exception e) - { - PrintException(null, e); - } - try - { - connection.Dispose(); - } - catch (Exception e) - { - PrintException(null, e); - } - } + connection.Open(); - private bool RunTestCoreAndCompareWithBaseline() - { - string outputPath = "MultipleResultsTest.out"; - string baselinePath = "MultipleResultsTest.bsl"; - - var fstream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.Read); - var swriter = new StreamWriter(fstream, Encoding.UTF8); - // Convert all string writes of '\n' to '\r\n' so output files can be 'text' not 'binary' - var twriter = new CarriageReturnLineFeedReplacer(swriter); - Console.SetOut(twriter); // "redirect" Console.Out - - // Run Test - RunTest(); - - Console.Out.Flush(); - Console.Out.Dispose(); - - // Recover the standard output stream - StreamWriter standardOutput = new StreamWriter(Console.OpenStandardOutput()); - standardOutput.AutoFlush = true; - Console.SetOut(standardOutput); - - // Compare output file - var comparisonResult = FindDiffFromBaseline(baselinePath, outputPath); - - if (string.IsNullOrEmpty(comparisonResult)) - { - return true; - } - - Console.WriteLine("Test Failed!"); - Console.WriteLine("Please compare baseline : {0} with output :{1}", Path.GetFullPath(baselinePath), Path.GetFullPath(outputPath)); - Console.WriteLine("Comparison Results : "); - Console.WriteLine(comparisonResult); - return false; - } + command.CommandText = s_sqlStatement; - private void PrintException(Type expected, Exception e, params string[] values) - { - try - { - Debug.Assert(e != null, "PrintException: null exception"); - - _globalBuilder.Length = 0; - _globalBuilder.Append(e.GetType().Name).Append(": "); - - if (e is COMException) - { - _globalBuilder.Append("0x").Append((((COMException)e).HResult).ToString("X8")); - if (expected != e.GetType()) - { - _globalBuilder.Append(": ").Append(e.ToString()); - } - } - else - { - _globalBuilder.Append(e.Message); - } - AssemblyFilter(_globalBuilder); - Console.WriteLine(_globalBuilder.ToString()); - - if (expected != e.GetType()) - { - Console.WriteLine(e.StackTrace); - } - if (values != null) - { - foreach (string value in values) - { - Console.WriteLine(value); - } - } - if (e.InnerException != null) - { - PrintException(e.InnerException.GetType(), e.InnerException); - } - Console.Out.Flush(); - } - catch (Exception f) - { - Console.WriteLine(f); - } + // ExecuteNonQuery will drain every result set, info message and exception, collating these into a single exception. + SqlException exNonQuery = Assert.Throws(() => command.ExecuteNonQuery()); + Assert.Equal($"{ResultSet2_Error}\n{ResultSet4_Error}\n{ResultSet6_Error}\n{ResultSet8_Error}\n{ResultSet10_Error}\n" + + $"{ResultSet1_Message}\n{ResultSet2_Message}\n{ResultSet3_Message}\n{ResultSet4_Message}\n{ResultSet5_Message}\n" + + $"{ResultSet6_Message}\n{ResultSet7_Message}\n{ResultSet8_Message}\n{ResultSet9_Message}\n{ResultSet10_Message}\n{ResultSet11_Message}", exNonQuery.Message.Replace("\r\n", "\n")); + Assert.Empty(messages); } - private string FindDiffFromBaseline(string baselinePath, string outputPath) + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + public void ExecuteScalar() { - var expectedLines = File.ReadAllLines(baselinePath); - var outputLines = File.ReadAllLines(outputPath); - - var comparisonSb = new StringBuilder(); - - // Start compare results - var expectedLength = expectedLines.Length; - var outputLength = outputLines.Length; - var findDiffLength = Math.Min(expectedLength, outputLength); - - // Find diff for each lines - for (var lineNo = 0; lineNo < findDiffLength; lineNo++) - { - if (!expectedLines[lineNo].Equals(outputLines[lineNo])) - { - comparisonSb.AppendFormat("** DIFF at line {0} \n", lineNo); - comparisonSb.AppendFormat("A : {0} \n", outputLines[lineNo]); - comparisonSb.AppendFormat("E : {0} \n", expectedLines[lineNo]); - } - } - - var startIndex = findDiffLength - 1; - if (startIndex < 0) - startIndex = 0; - - if (findDiffLength < expectedLength) - { - comparisonSb.AppendFormat("** MISSING \n"); - for (var lineNo = startIndex; lineNo < expectedLength; lineNo++) - { - comparisonSb.AppendFormat("{0} : {1}", lineNo, expectedLines[lineNo]); - } - } - if (findDiffLength < outputLength) - { - comparisonSb.AppendFormat("** EXTRA \n"); - for (var lineNo = startIndex; lineNo < outputLength; lineNo++) - { - comparisonSb.AppendFormat("{0} : {1}", lineNo, outputLines[lineNo]); - } - } - - return comparisonSb.ToString(); - } + using SqlConnection connection = new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MultipleActiveResultSets = true }).ConnectionString); + using SqlCommand command = connection.CreateCommand(); + ConcurrentQueue messages = new ConcurrentQueue(); - private string AssemblyFilter(StreamWriter writer) - { - if (_outputBuilder == null) - { - _outputBuilder = new StringBuilder(); - } - _outputBuilder.Length = 0; - - byte[] utf8 = ((MemoryStream)writer.BaseStream).ToArray(); - string value = System.Text.Encoding.UTF8.GetString(utf8, 3, utf8.Length - 3); // skip 0xEF, 0xBB, 0xBF - _outputBuilder.Append(value); - AssemblyFilter(_outputBuilder); - return _outputBuilder.ToString(); + connection.InfoMessage += (object sender, SqlInfoMessageEventArgs args) => + messages.Enqueue(args.Message); + + connection.Open(); + + command.CommandText = s_sqlStatement; + + // ExecuteScalar will select the first result set and the info message preceding it, then stop. + command.ExecuteScalar(); + Assert.True(messages.TryDequeue(out string lastMessage)); + Assert.Empty(messages); + Assert.Equal(ResultSet1_Message, lastMessage); } - private void AssemblyFilter(StringBuilder builder) + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + public void ExecuteReader() { - string[] filter = _outputFilter; - if (filter == null) - { - filter = new string[5]; - string tmp = typeof(System.Guid).AssemblyQualifiedName; - filter[0] = tmp.Substring(tmp.IndexOf(',')); - filter[1] = filter[0].Replace("mscorlib", "System"); - filter[2] = filter[0].Replace("mscorlib", "System.Data"); - filter[3] = filter[0].Replace("mscorlib", "System.Data.OracleClient"); - filter[4] = filter[0].Replace("mscorlib", "System.Xml"); - _outputFilter = filter; - } - - for (int i = 0; i < filter.Length; ++i) - { - builder.Replace(filter[i], ""); - } + using SqlConnection connection = new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MultipleActiveResultSets = true }).ConnectionString); + using SqlCommand command = connection.CreateCommand(); + ConcurrentQueue messages = new ConcurrentQueue(); + + connection.InfoMessage += (object sender, SqlInfoMessageEventArgs args) => + messages.Enqueue(args.Message); + + connection.Open(); + + command.CommandText = s_sqlStatement; + + // SqlDataReader will drain every result set it's told to, throwing exceptions and printing messages as it goes. + using SqlDataReader reader = command.ExecuteReader(); + + // Result set 1: a result set and a message of '0'. + // Result set 2: a message of '1' and an exception. + AdvanceReader(reader, messages, ResultSet1_Message, ResultSet2_Message, ResultSet2_Error, finalBlock: false); + + // Result set 3: a result set and a message of '3'. + // Result set 4: a message of '4' and an exception. + AdvanceReader(reader, messages, ResultSet3_Message, ResultSet4_Message, ResultSet4_Error, finalBlock: false); + + // Result set 5: a result set and a message of '5'. + // Result set 6: a message of '6' and an exception. + AdvanceReader(reader, messages, ResultSet5_Message, ResultSet6_Message, ResultSet6_Error, finalBlock: false); + + // Result set 7: a result set and a message of '7'. + // Result set 8: a message of '8' and an exception. + AdvanceReader(reader, messages, ResultSet7_Message, ResultSet8_Message, ResultSet8_Error, finalBlock: false); + + // Result set 9: a result set and a message of '9'. + // Result set 10: a message of '10' and an exception. + AdvanceReader(reader, messages, ResultSet9_Message, ResultSet10_Message, ResultSet10_Error, finalBlock: true); + + // One message following the final result set + Assert.True(messages.TryDequeue(out string lastMessage)); + Assert.Empty(messages); + Assert.Equal(ResultSet11_Message, lastMessage); } - /// - /// special wrapper for the text writer to replace single "\n" with "\n" - /// - private sealed class CarriageReturnLineFeedReplacer : TextWriter + private static void AdvanceReader(SqlDataReader reader, ConcurrentQueue messageBuffer, string resultSet1Message, string resultSet2Message, string resultSet2ExceptionMessage, bool finalBlock) { - private TextWriter _output; - private int _lineFeedCount; - private bool _hasCarriageReturn; - - internal CarriageReturnLineFeedReplacer(TextWriter output) - { - if (output == null) - throw new ArgumentNullException(nameof(output)); - - _output = output; - } - - public int LineFeedCount - { - get { return _lineFeedCount; } - } - - public override Encoding Encoding - { - get { return _output.Encoding; } - } - - public override IFormatProvider FormatProvider - { - get { return _output.FormatProvider; } - } - - public override string NewLine - { - get { return _output.NewLine; } - set { _output.NewLine = value; } - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - ((IDisposable)_output).Dispose(); - } - _output = null; - } - - public override void Flush() - { - _output.Flush(); - } - - public override void Write(char value) - { - if ('\n' == value) - { - _lineFeedCount++; - if (!_hasCarriageReturn) - { // X'\n'Y -> X'\r\n'Y - _output.Write('\r'); - } - } - _hasCarriageReturn = '\r' == value; - _output.Write(value); - } + bool moreResults = true; + + // This is a pair of result sets: + // Result set 1: an info message of something and a result set + // Result set 2: an info message of something and an exception + Assert.True(messageBuffer.TryDequeue(out string lastMessage)); + Assert.Empty(messageBuffer); + Assert.Equal(resultSet1Message, lastMessage); + + SqlException exReader = Assert.Throws(() => moreResults = reader.NextResult()); + Assert.Equal(resultSet2ExceptionMessage, exReader.Message); + + Assert.True(messageBuffer.TryDequeue(out lastMessage)); + Assert.Empty(messageBuffer); + Assert.Equal(resultSet2Message, lastMessage); + + moreResults = reader.NextResult(); + Assert.Equal(finalBlock, !moreResults); } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs index d1fe3bf6ac..8b5b6d0a40 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs @@ -1495,27 +1495,6 @@ private void WriteReader(SqlDataReader rdr) while (rdr.NextResult()); } - private void DumpSqlParam(SqlParameter param) - { - Console.WriteLine("Parameter {0}", param.ParameterName); - Console.WriteLine(" IsNullable: {0}", param.IsNullable); - Console.WriteLine(" LocaleId: {0}", param.LocaleId); - Console.WriteLine(" Offset: {0}", param.Offset); - Console.WriteLine(" CompareInfo: {0}", param.CompareInfo); - Console.WriteLine(" DbType: {0}", param.DbType); - Console.WriteLine(" Direction: {0}", param.Direction); - Console.WriteLine(" Precision: {0}", param.Precision); - Console.WriteLine(" Scale: {0}", param.Scale); - Console.WriteLine(" Size: {0}", param.Size); - Console.WriteLine(" SqlDbType: {0}", param.SqlDbType); - Console.WriteLine(" TypeName: {0}", param.TypeName); - //Console.WriteLine(" UdtTypeName: {0}", param.UdtTypeName); - Console.WriteLine(" XmlSchemaCollectionDatabase: {0}", param.XmlSchemaCollectionDatabase); - Console.WriteLine(" XmlSchemaCollectionName: {0}", param.XmlSchemaCollectionName); - Console.WriteLine(" XmlSchemaCollectionSchema: {0}", param.XmlSchemaCollectionOwningSchema); - } - - #endregion } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs index 2e6e3d0dc6..a459831ced 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs @@ -51,7 +51,7 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool server._endpoint = new TDSServerEndPoint(server) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. - server._endpoint.EventLog = Console.Out; + server._endpoint.EventLog = enableLog ? Console.Out : null; server._endpoint.Start(); int port = server._endpoint.ServerEndPoint.Port; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs index eda4de8e2a..1933444df6 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs @@ -132,7 +132,7 @@ public static TransientFaultTDSServer StartServerWithQueryEngine(QueryEngine eng server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. - server._endpoint.EventLog = Console.Out; + server._endpoint.EventLog = enableLog ? Console.Out : null; server._endpoint.Start(); server.Port = server._endpoint.ServerEndPoint.Port; From 1fcd48dbae5356ccd44715c4600cae62f96755d1 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:00:02 +0000 Subject: [PATCH 2/7] Further console logging disabled based on CI results. Also adjusted certificate generation, it's redirecting standard errors and not always loading the user profile. --- .../tests/FunctionalTests/SqlConnectionBasicTests.cs | 8 ++++---- .../AADFedAuthTokenRefreshTest.cs | 2 ++ .../Fixtures/CertificateFixtureBase.cs | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 6bbc44f6b1..cf5374044c 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -65,7 +65,7 @@ public async Task PreLoginEncryptionExcludedTest() [PlatformSpecific(TestPlatforms.Windows)] public async Task TransientFaultTestAsync(uint errorCode) { - using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, false, errorCode); SqlConnectionStringBuilder builder = new() { DataSource = "localhost," + server.Port, @@ -85,7 +85,7 @@ public async Task TransientFaultTestAsync(uint errorCode) [PlatformSpecific(TestPlatforms.Windows)] public void TransientFaultTest(uint errorCode) { - using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, false, errorCode); SqlConnectionStringBuilder builder = new() { DataSource = "localhost," + server.Port, @@ -112,7 +112,7 @@ public void TransientFaultTest(uint errorCode) [PlatformSpecific(TestPlatforms.Windows)] public void TransientFaultDisabledTestAsync(uint errorCode) { - using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, false, errorCode); SqlConnectionStringBuilder builder = new() { DataSource = "localhost," + server.Port, @@ -134,7 +134,7 @@ public void TransientFaultDisabledTestAsync(uint errorCode) [PlatformSpecific(TestPlatforms.Windows)] public void TransientFaultDisabledTest(uint errorCode) { - using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, false, errorCode); SqlConnectionStringBuilder builder = new() { DataSource = "localhost," + server.Port, diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AADFedAuthTokenRefreshTest/AADFedAuthTokenRefreshTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AADFedAuthTokenRefreshTest/AADFedAuthTokenRefreshTest.cs index 875d755a59..027acfde23 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AADFedAuthTokenRefreshTest/AADFedAuthTokenRefreshTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AADFedAuthTokenRefreshTest/AADFedAuthTokenRefreshTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using Microsoft.Data.SqlClient.ManualTesting.Tests.SQL.Common.SystemDataInternals; using Xunit; using Xunit.Abstractions; @@ -66,6 +67,7 @@ public void FedAuthTokenRefreshTest() } } + [Conditional("DEBUG")] private void LogInfo(string message) { _testOutputHelper.WriteLine(message); diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Fixtures/CertificateFixtureBase.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Fixtures/CertificateFixtureBase.cs index 79699c32d5..ae7bd0262c 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Fixtures/CertificateFixtureBase.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Fixtures/CertificateFixtureBase.cs @@ -146,11 +146,13 @@ exit 1 { FileName = "powershell.exe", RedirectStandardOutput = true, + RedirectStandardError = false, UseShellExecute = false, CreateNoWindow = true, // Pass the Base64-encoded command to remove the need to escape quote marks Arguments = "-EncodedCommand " + Convert.ToBase64String(Encoding.Unicode.GetBytes(formattedCommand)), - Verb = "runas" + Verb = "runas", + LoadUserProfile = true } }) { From 33c6cc75a1bbdba8831b17f37a1647dff404158e Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Thu, 5 Dec 2024 07:29:04 +0000 Subject: [PATCH 3/7] Disabling TDSServer debug logging in one diagnostic test --- .../tests/ManualTests/TracingTests/DiagnosticTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs index 5d5c9d5ec7..b8649d43d2 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs @@ -430,7 +430,7 @@ public void ConnectionOpenTest() { sqlConnection.Open(); } - }, true); + }); return RemoteExecutor.SuccessExitCode; }).Dispose(); } From 0c9c4670ecae6605eaa8a7d4dcbd69b2dc8c769c Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Wed, 19 Feb 2025 05:49:38 +0000 Subject: [PATCH 4/7] Remove CustomDeviceFlowCallback --- .../tests/FunctionalTests/AADAuthenticationTests.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs index 43e0be9101..e97b251613 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs @@ -53,7 +53,7 @@ private void InvalidCombinationCheck(SqlCredential credential) [Fact] public void CustomActiveDirectoryProviderTest() { - SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback); + SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(static (result) => Task.CompletedTask); SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, authProvider); Assert.Equal(authProvider, SqlAuthenticationProvider.GetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow)); } @@ -69,14 +69,9 @@ public void CustomActiveDirectoryProviderTest_AppClientId() [Fact] public void CustomActiveDirectoryProviderTest_AppClientId_DeviceFlowCallback() { - SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback, Guid.NewGuid().ToString()); + SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(static (result) => Task.CompletedTask, Guid.NewGuid().ToString()); SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, authProvider); Assert.Equal(authProvider, SqlAuthenticationProvider.GetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow)); } - - private Task CustomDeviceFlowCallback(DeviceCodeResult result) - { - return Task.FromResult(0); - } } } From ee43e031f37e97c79b51a666cd3b7b2c3093ec7e Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Mon, 24 Feb 2025 06:02:42 +0000 Subject: [PATCH 5/7] Early response to code review --- .../MultipleResultsTest.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs index a654fec8ed..3afe433087 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs @@ -60,9 +60,25 @@ public void ExecuteNonQuery() // ExecuteNonQuery will drain every result set, info message and exception, collating these into a single exception. SqlException exNonQuery = Assert.Throws(() => command.ExecuteNonQuery()); - Assert.Equal($"{ResultSet2_Error}\n{ResultSet4_Error}\n{ResultSet6_Error}\n{ResultSet8_Error}\n{ResultSet10_Error}\n" + - $"{ResultSet1_Message}\n{ResultSet2_Message}\n{ResultSet3_Message}\n{ResultSet4_Message}\n{ResultSet5_Message}\n" + - $"{ResultSet6_Message}\n{ResultSet7_Message}\n{ResultSet8_Message}\n{ResultSet9_Message}\n{ResultSet10_Message}\n{ResultSet11_Message}", exNonQuery.Message.Replace("\r\n", "\n")); + string expectedInfoMessages = + $"{ResultSet2_Error}\n" + + $"{ResultSet4_Error}\n" + + $"{ResultSet6_Error}\n" + + $"{ResultSet8_Error}\n" + + $"{ResultSet10_Error}\n" + + $"{ResultSet1_Message}\n" + + $"{ResultSet2_Message}\n" + + $"{ResultSet3_Message}\n" + + $"{ResultSet4_Message}\n" + + $"{ResultSet5_Message}\n" + + $"{ResultSet6_Message}\n" + + $"{ResultSet7_Message}\n" + + $"{ResultSet8_Message}\n" + + $"{ResultSet9_Message}\n" + + $"{ResultSet10_Message}\n" + + $"{ResultSet11_Message}"; + + Assert.Equal(expectedInfoMessages, exNonQuery.Message.Replace("\r\n", "\n")); Assert.Empty(messages); } From 29a3fa4869cbb7a78a9d896d84edda6750423cb9 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Mon, 24 Feb 2025 06:45:30 +0000 Subject: [PATCH 6/7] Checked use of Environment.NewLine --- .../MultipleResultsTest.cs | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs index 3afe433087..ce94874d8b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.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; using System.Collections.Concurrent; using Xunit; @@ -60,25 +61,14 @@ public void ExecuteNonQuery() // ExecuteNonQuery will drain every result set, info message and exception, collating these into a single exception. SqlException exNonQuery = Assert.Throws(() => command.ExecuteNonQuery()); - string expectedInfoMessages = - $"{ResultSet2_Error}\n" + - $"{ResultSet4_Error}\n" + - $"{ResultSet6_Error}\n" + - $"{ResultSet8_Error}\n" + - $"{ResultSet10_Error}\n" + - $"{ResultSet1_Message}\n" + - $"{ResultSet2_Message}\n" + - $"{ResultSet3_Message}\n" + - $"{ResultSet4_Message}\n" + - $"{ResultSet5_Message}\n" + - $"{ResultSet6_Message}\n" + - $"{ResultSet7_Message}\n" + - $"{ResultSet8_Message}\n" + - $"{ResultSet9_Message}\n" + - $"{ResultSet10_Message}\n" + - $"{ResultSet11_Message}"; - - Assert.Equal(expectedInfoMessages, exNonQuery.Message.Replace("\r\n", "\n")); + + string expectedInfoMessages = string.Join(Environment.NewLine, + ResultSet2_Error, ResultSet4_Error, ResultSet6_Error, ResultSet8_Error, ResultSet10_Error, + ResultSet1_Message, ResultSet2_Message, ResultSet3_Message, ResultSet4_Message, ResultSet5_Message, + ResultSet6_Message, ResultSet7_Message, ResultSet8_Message, ResultSet9_Message, ResultSet10_Message, + ResultSet11_Message); + + Assert.Equal(expectedInfoMessages, exNonQuery.Message); Assert.Empty(messages); } From f08500565feae97d60406310c55251b32c15dafb Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Mon, 24 Feb 2025 06:56:29 +0000 Subject: [PATCH 7/7] Separated Assert.Throws call --- .../MultipleResultsTest/MultipleResultsTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs index ce94874d8b..199b93e15f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/ProviderAgnostic/MultipleResultsTest/MultipleResultsTest.cs @@ -60,7 +60,8 @@ public void ExecuteNonQuery() command.CommandText = s_sqlStatement; // ExecuteNonQuery will drain every result set, info message and exception, collating these into a single exception. - SqlException exNonQuery = Assert.Throws(() => command.ExecuteNonQuery()); + Func testCode = () => command.ExecuteNonQuery(); + SqlException exNonQuery = Assert.Throws(testCode); string expectedInfoMessages = string.Join(Environment.NewLine, ResultSet2_Error, ResultSet4_Error, ResultSet6_Error, ResultSet8_Error, ResultSet10_Error,