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