diff --git a/src/Microsoft.Data.SqlClient/tests/Common/SqlDataReaderExtensions.cs b/src/Microsoft.Data.SqlClient/tests/Common/SqlDataReaderExtensions.cs
index 43c7bde4bd..dd2dcb0d4b 100644
--- a/src/Microsoft.Data.SqlClient/tests/Common/SqlDataReaderExtensions.cs
+++ b/src/Microsoft.Data.SqlClient/tests/Common/SqlDataReaderExtensions.cs
@@ -2,6 +2,9 @@
// 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.Threading;
+using System.Threading.Tasks;
+
namespace Microsoft.Data.SqlClient.Tests.Common
{
///
@@ -13,14 +16,55 @@ public static class SqlDataReaderExtensions
/// Reads all result sets in the provided and discards them.
///
/// Reader to flush results from.
- public static void FlushAllResults(this SqlDataReader dataReader)
+ ///
+ /// If true, the records in each result set will be flushed, too. If false
+ /// only will be the only method called.
+ ///
+ public static void FlushAllResults(this SqlDataReader dataReader, bool flushResults = true)
{
do
{
- dataReader.FlushResultSet();
+ if (flushResults)
+ {
+ dataReader.FlushResultSet();
+ }
} while (dataReader.NextResult());
}
+ ///
+ /// Reads all result sets in the provided and discards them.
+ ///
+ /// Reader to flush results from.
+ ///
+ /// If true, the records in each result set will be flushed, too. If false
+ /// only will be the only method called.
+ ///
+ public static Task FlushAllResultsAsync(this SqlDataReader dataReader, bool flushResults = true) =>
+ FlushAllResultsAsync(dataReader, CancellationToken.None, flushResults);
+
+ ///
+ /// Reads all result sets in the provided and discards them.
+ ///
+ /// Reader to flush results from.
+ /// Token to use for premature cancellation of the task.
+ ///
+ /// If true, the records in each result set will be flushed, too. If false
+ /// only will be the only method called.
+ ///
+ public static async Task FlushAllResultsAsync(
+ this SqlDataReader dataReader,
+ CancellationToken cancellationToken,
+ bool flushResults = true)
+ {
+ do
+ {
+ if (flushResults)
+ {
+ await dataReader.FlushResultSetAsync(cancellationToken).ConfigureAwait(false);
+ }
+ } while (await dataReader.NextResultAsync(cancellationToken).ConfigureAwait(false));
+ }
+
///
/// Reads all results in the current result set of the provided
/// and discards them.
@@ -33,5 +77,27 @@ public static void FlushResultSet(this SqlDataReader dataReader)
// Discard results.
}
}
+
+ ///
+ /// Reads all results in the current result set of the provided
+ /// and discards them.
+ ///
+ /// Reader to flush results from.
+ public static Task FlushResultSetAsync(this SqlDataReader dataReader) =>
+ FlushResultSetAsync(dataReader, CancellationToken.None);
+
+ ///
+ /// Reads all results in the current result set of the provided
+ /// and discards them.
+ ///
+ /// Reader to flush results from.
+ /// Token to use for premature cancellation of the task.
+ public static async Task FlushResultSetAsync(this SqlDataReader dataReader, CancellationToken cancellationToken)
+ {
+ while (await dataReader.ReadAsync(cancellationToken).ConfigureAwait(false))
+ {
+ // Discard results.
+ }
+ }
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj
index 7f6d8abd2c..99287f012d 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj
@@ -47,14 +47,12 @@
-
-
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs
index efa7962d28..76270480bf 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs
@@ -53,7 +53,7 @@ public static void PassThroughSinglePacket(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -67,7 +67,7 @@ public static void PassThroughMultiplePacket(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -81,7 +81,7 @@ public static void PassThroughMultiplePacketWithShortEnd(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -96,7 +96,7 @@ public static void ReconstructSinglePacket(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -115,7 +115,7 @@ public static void Reconstruct2Packets_Part_PartFull(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -134,7 +134,7 @@ public static void Reconstruct2Packets_Full_FullPart_Part(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -154,7 +154,7 @@ public static void ReconstructMultiplePacketSequence(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -173,7 +173,7 @@ public static void ReconstructMultiplePacketSequenceWithShortEnd(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))]
@@ -189,7 +189,7 @@ public static void Reconstruct3Packets_PartPartPart(bool isAsync)
var output = MultiplexPacketList(isAsync, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalFact(nameof(IsUsingModernProcessSni))]
@@ -208,7 +208,7 @@ public static void TrailingPartialPacketInSnapshotNotDuplicated()
var output = MultiplexPacketList(true, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ConditionalFact(nameof(IsUsingModernProcessSni))]
@@ -252,7 +252,7 @@ public static void MultipleFullPacketsInRemainderAreSplitCorrectly()
var output = MultiplexPacketList(false, dataSize, input);
- ComparePacketLists(dataSize, expected, output);
+ ComparePacketLists(expected, output);
}
[ExcludeFromCodeCoverage]
@@ -269,16 +269,14 @@ private static List MultiplexPacketList(bool isAsync, int dataSize,
if (stateObject._inBytesRead > 0)
{
- if (
- stateObject._inBytesRead < TdsEnums.HEADER_LEN
- ||
- stateObject._inBytesRead != (TdsEnums.HEADER_LEN +
- Packet.GetDataLengthFromHeader(
- stateObject._inBuff.AsSpan(0, TdsEnums.HEADER_LEN)))
- )
- {
- Assert.Fail("incomplete packet exposed after call to ProcessSniPacket");
- }
+ // At least the header must be read
+ Assert.False(stateObject._inBytesRead < TdsEnums.HEADER_LEN);
+
+ // The full packet must be read, too
+ Span header = stateObject._inBuff.AsSpan(0, TdsEnums.HEADER_LEN);
+ int packetLength = Packet.GetDataLengthFromHeader(header);
+ int expectedLength = TdsEnums.HEADER_LEN + packetLength;
+ Assert.Equal(expectedLength, stateObject._inBytesRead);
if (!isAsync)
{
@@ -299,17 +297,14 @@ private static List MultiplexPacketList(bool isAsync, int dataSize,
if (stateObject._inBytesRead > 0)
{
- if (
- stateObject._inBytesRead < TdsEnums.HEADER_LEN
- ||
- stateObject._inBytesRead != (TdsEnums.HEADER_LEN +
- Packet.GetDataLengthFromHeader(
- stateObject._inBuff.AsSpan(0, TdsEnums.HEADER_LEN)))
- )
- {
- Assert.Fail(
- "incomplete packet exposed after call to ProcessSniPacket with usePartialPacket");
- }
+ // Header must at least have been read
+ Assert.False(stateObject._inBytesRead < TdsEnums.HEADER_LEN);
+
+ // Full packet must have been read
+ Span header = stateObject._inBuff.AsSpan(0, TdsEnums.HEADER_LEN);
+ int packetLength = Packet.GetDataLengthFromHeader(header);
+ int expectedLength = TdsEnums.HEADER_LEN + packetLength;
+ Assert.Equal(expectedLength, stateObject._inBytesRead);
output.Add(PacketData.Copy(stateObject._inBuff, stateObject._inBytesUsed,
stateObject._inBytesRead));
@@ -326,7 +321,7 @@ private static List MultiplexPacketList(bool isAsync, int dataSize,
}
[ExcludeFromCodeCoverage]
- private static void ComparePacketLists(int dataSize, List expected, List output)
+ private static void ComparePacketLists(List expected, List output)
{
Assert.NotNull(expected);
Assert.NotNull(output);
@@ -334,15 +329,10 @@ private static void ComparePacketLists(int dataSize, List expected,
for (int index = 0; index < expected.Count; index++)
{
- var a = expected[index];
- var b = output[index];
-
- var compare = a.AsSpan().SequenceCompareTo(b.AsSpan());
-
- if (compare != 0)
- {
- Assert.Fail($"expected data does not match output data at packet index {index}");
- }
+ Span a = expected[index].AsSpan();
+ Span b = output[index].AsSpan();
+
+ Assert.True(a.SequenceEqual(b), $"Packet data was not equal at index {index}");
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorCollectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorCollectionTest.cs
deleted file mode 100644
index 32f236c761..0000000000
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorCollectionTest.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections;
-using Xunit;
-
-namespace Microsoft.Data.SqlClient.Tests
-{
- public class SqlErrorCollectionTest
- {
- private const string badServer = "92B96911A0BD43E8ADA4451031F7E7CF";
-
- [Fact]
- public void IsSynchronized_Success()
- {
- ICollection c = CreateCollection();
- Assert.False(c.IsSynchronized);
- }
-
- [Fact]
- public void SyncRoot_Success()
- {
- ICollection c = CreateCollection();
- Assert.Same(c, c.SyncRoot);
- }
-
- [Fact]
- public void Indexer_Success()
- {
- SqlErrorCollection c = CreateCollection();
- Assert.NotNull(c[0]);
- Assert.Same(c[0], c[0]);
- }
-
- [Fact]
- public void Indexer_Throws()
- {
- SqlErrorCollection c = CreateCollection();
-
- AssertExtensions.Throws("index", () => c[-1]);
- AssertExtensions.Throws("index", () => c[c.Count]);
- }
-
- [Fact]
- public void CopyTo_Success()
- {
- ValidateCopyTo((collection, array, index) => collection.CopyTo(array, index));
- }
-
- [Fact]
- public void CopyTo_NonGeneric_Success()
- {
- ValidateCopyTo((collection, array, index) => ((ICollection)collection).CopyTo(array, index));
- }
-
- private static void ValidateCopyTo(Action copyTo)
- {
- SqlErrorCollection c = CreateCollection();
- SqlError[] destination = new SqlError[5];
-
- copyTo(c, destination, 2);
-
- Assert.Null(destination[0]);
- Assert.Null(destination[1]);
- Assert.Same(c[0], destination[2]);
- Assert.Null(destination[3]);
- Assert.Null(destination[4]);
- }
-
- [Fact]
- public void CopyTo_Throws()
- {
- ValidateCopyToThrows((collection, array, index) => collection.CopyTo(array, index));
- }
-
- [Fact]
- public void CopyTo_NonGeneric_Throws()
- {
- ValidateCopyToThrows((collection, array, index) => ((ICollection)collection).CopyTo(array, index), c =>
- {
- ICollection ic = c;
- AssertExtensions.Throws(null, () => ic.CopyTo(new SqlError[4, 3], 0));
- Assert.Throws(() => ic.CopyTo(new string[10], 0));
- });
- }
-
- private static void ValidateCopyToThrows(
- Action copyTo,
- Action additionalValidation = null)
- {
- SqlErrorCollection c = CreateCollection();
-
- Assert.Throws(() => copyTo(c, null, 0));
- Assert.Throws(() => copyTo(c, null, -1));
- Assert.Throws(() => copyTo(c, new SqlError[10], -1));
- AssertExtensions.Throws("destinationArray", "", () => copyTo(c, new SqlError[10], 1000));
-
- additionalValidation?.Invoke(c);
- }
-
- [Fact]
- public void GetEnumerator_Success()
- {
- SqlErrorCollection c = CreateCollection();
-
- IEnumerator e = c.GetEnumerator();
-
- Assert.NotNull(e);
- Assert.NotSame(e, c.GetEnumerator());
-
- for (int i = 0; i < 2; i++)
- {
- Assert.Throws(() => e.Current);
-
- Assert.True(e.MoveNext());
- Assert.Same(c[0], e.Current);
-
- Assert.False(e.MoveNext());
- Assert.False(e.MoveNext());
- Assert.False(e.MoveNext());
-
- Assert.Throws(() => e.Current);
-
- e.Reset();
- }
- }
-
- private static SqlErrorCollection CreateCollection()
- {
- var builder = new SqlConnectionStringBuilder()
- {
- DataSource = badServer,
- ConnectTimeout = 1,
- Pooling = false
- };
-
- using (var connection = new SqlConnection(builder.ConnectionString))
- {
- try
- {
- connection.Open();
- }
- catch (SqlException ex)
- {
- Assert.NotNull(ex.Errors);
- Assert.Single(ex.Errors);
-
- return ex.Errors;
- }
- }
-
- throw new InvalidOperationException("SqlException.Errors should have been returned.");
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs
deleted file mode 100644
index ee05379870..0000000000
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.IO;
-using System.Reflection;
-using System.Runtime.Serialization;
-using Xunit;
-
-namespace Microsoft.Data.SqlClient.Tests
-{
- public class SqlErrorTest
- {
- private const string SQLMSF_FailoverPartnerNotSupported =
- "Connecting to a mirrored SQL Server instance using the MultiSubnetFailover connection option is not supported.";
- private const byte FATAL_ERROR_CLASS = 20;
-
-#if NETFRAMEWORK
- [Fact]
- public static void SqlErrorSerializationTest()
- {
- DataContractSerializer serializer = new DataContractSerializer(typeof(SqlError));
- SqlError expected = CreateError();
- SqlError actual = null;
- using (var stream = new MemoryStream())
- {
- try
- {
- serializer.WriteObject(stream, expected);
- stream.Position = 0;
- actual = (SqlError)serializer.ReadObject(stream);
- }
- catch (Exception ex)
- {
- Assert.Fail($"Unexpected Exception occurred: {ex.Message}");
- }
- }
-
- Assert.Equal(expected.Message, actual.Message);
- Assert.Equal(expected.Number, actual.Number);
- Assert.Equal(expected.State, actual.State);
- Assert.Equal(expected.Class, actual.Class);
- Assert.Equal(expected.Server, actual.Server);
- Assert.Equal(expected.Procedure, actual.Procedure);
- Assert.Equal(expected.LineNumber, actual.LineNumber);
- Assert.Equal(expected.Source, actual.Source);
- }
-#endif
-
-
- private static SqlError CreateError()
- {
- string msg = SQLMSF_FailoverPartnerNotSupported;
-
- Type sqlErrorType = typeof(SqlError);
-
- // SqlError only has internal constructors, in order to instantiate this, we use reflection
- SqlError sqlError = (SqlError)sqlErrorType.Assembly.CreateInstance(
- sqlErrorType.FullName,
- false,
- BindingFlags.Instance | BindingFlags.NonPublic,
- null,
- new object[] { 100, (byte)0x00, FATAL_ERROR_CLASS, "ServerName", msg, "ProcedureName", 10, null, -1 },
- null,
- null);
-
- return sqlError;
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs
index 7d63e9b98f..5fab83f925 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs
@@ -14,6 +14,7 @@
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
using Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.Setup;
using Microsoft.Data.SqlClient.ManualTesting.Tests.SystemDataInternals;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted
@@ -2455,7 +2456,6 @@ public void TestRetryWhenAEParameterMetadataCacheIsStale(string connectionString
{
Assert.Equal(customerId, (int)reader[0]);
}
- reader.Close();
};
// change the CEK for the CustomerId column from ColumnEncryptionKey1 to ColumnEncryptionKey2
@@ -2474,7 +2474,6 @@ public void TestRetryWhenAEParameterMetadataCacheIsStale(string connectionString
{
Assert.Equal(customerId, (int)reader[0]);
}
- reader.Close();
}
// revert the CEK change to the CustomerId column
@@ -2522,7 +2521,6 @@ public void TestRetryWhenAEEnclaveCacheIsStale(string connectionString)
{
Assert.Equal(customerId, (int)reader[0]);
}
- reader.Close();
}
CommandHelper.InvalidateEnclaveSession(cmd);
@@ -2534,7 +2532,6 @@ public void TestRetryWhenAEEnclaveCacheIsStale(string connectionString)
{
Assert.Equal(customerId, (int)reader[0]);
}
- reader.Close();
}
CommandHelper.InvalidateEnclaveSession(cmd);
@@ -2568,7 +2565,6 @@ public void TestRetryWhenAEEnclaveCacheIsStale(string connectionString)
{
Assert.Equal(customerId, (int)reader[0]);
}
- reader.Close();
}
CommandHelper.ForceThrowDuringGenerateEnclavePackage(cmd);
@@ -2863,11 +2859,8 @@ private async Task ExecuteScalarAsync(SqlCommand sqlCommand, CancellationToken c
///
private async Task ExecuteReaderAsync(SqlCommand sqlCommand, CancellationToken cancellationToken)
{
- using (SqlDataReader reader = await sqlCommand.ExecuteReaderAsync(cancellationToken))
- {
- while (await reader.ReadAsync())
- { }
- }
+ using SqlDataReader reader = await sqlCommand.ExecuteReaderAsync(cancellationToken);
+ await reader.FlushResultSetAsync();
}
///
@@ -3027,7 +3020,7 @@ private void EndExecuteReaderAsyncCallBack(IAsyncResult asyncResult)
catch (Exception e)
{
testAsyncCallBackStateObject.Completion.SetException(e);
- Assert.Fail($"{e.Message}");
+ throw;
}
}
@@ -3183,9 +3176,10 @@ private void TestCancellationToken(FieldInfo failpoint, SqlCommand sqlCommand, i
Console.WriteLine($"Cancellation produced non-SqlException: {ex}");
}
}
+
if (unexpected)
{
- Assert.Fail("Unexpected exceptions encountered; see console for details.");
+ throw;
}
}
@@ -3221,7 +3215,6 @@ private void Thread_ExecuteReader(object state)
{
TestCommandCancelParams cancelCommandTestParamsObject = state as TestCommandCancelParams;
SqlCommand sqlCommand = cancelCommandTestParamsObject?.SqlCommand;
- SqlDataReader reader = null;
Assert.True(cancelCommandTestParamsObject != null, @"cancelCommandTestParamsObject should not be null.");
Assert.True(sqlCommand != null, "sqlCommand should not be null.");
@@ -3233,24 +3226,21 @@ private void Thread_ExecuteReader(object state)
Exception ex = Assert.ThrowsAny(() =>
{
- reader = sqlCommand.ExecuteReader();
- while (reader.Read())
- { }
+ using SqlDataReader reader = sqlCommand.ExecuteReader();
+ reader.FlushResultSet();
});
// We don't use Assert.Contains() here because it truncates the
// actual and expected strings when outputting a failure.
if (!_cancellationExceptionMessages.Contains(ex.Message))
{
- Assert.Fail(
- $"Exception message \"{ex.Message}\" not found in: [\"" +
- string.Join("\", \"", _cancellationExceptionMessages) + "\"]");
+ string joinedExceptionList = string.Join("\", \"", _cancellationExceptionMessages);
+ Assert.Fail($"Exception message \"{ex.Message}\" not found in: [\"{joinedExceptionList}\"]");
}
}
finally
{
- reader?.Dispose();
- // ...and unlock the cancellation thread once we finish.
+ // Unlock the cancellation thread once we finish.
cancelCommandTestParamsObject.WorkloadCompleteSignal.Set();
}
}
@@ -3274,9 +3264,8 @@ private void Thread_ExecuteNonQuery(object state)
// actual and expected strings when outputting a failure.
if (!_cancellationExceptionMessages.Contains(ex.Message))
{
- Assert.Fail(
- $"Exception message \"{ex.Message}\" not found in: [\"" +
- string.Join("\", \"", _cancellationExceptionMessages) + "\"]");
+ string joinedExceptions = string.Join("\", \"", _cancellationExceptionMessages);
+ Assert.Fail($"Exception message \"{ex.Message}\" not found in: [\"{joinedExceptions}\"]");
}
}
finally
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs
index f54609e2c0..90d7a9fadb 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs
@@ -28,6 +28,17 @@ public sealed class ConversionTests : IDisposable, IClassFixture GenerateOutOfRangeValuesForType(SqlDbType type, int length
return list;
}
- ///
- /// Check if this exception is expected.
- ///
- ///
- ///
- private bool IsExpectedException(Exception e)
- {
- return e is OverflowException ||
- e is InvalidCastException ||
- e is SqlTypeException ||
- e is ArgumentException ||
- e is FormatException ||
- e is SqlException;
- }
-
///
/// Try to execute the command and check if there was an error if one was expected.
///
@@ -581,32 +577,9 @@ private void ExecuteAndCheckForError(SqlCommand sqlCmd, bool expectError)
}
else
{
- try
- {
- sqlCmd.ExecuteNonQuery();
- StringBuilder builder = new(
- "We should have gotten an error but passed instead; " +
- $"command: {sqlCmd.CommandText}; parameters: ");
- foreach (SqlParameter param in sqlCmd.Parameters)
- {
- builder.Append('(');
- builder.Append(param.ParameterName);
- builder.Append(' ');
- builder.Append(param.SqlDbType);
- builder.Append(' ');
- builder.Append(param.Value);
- builder.Append(") ");
- }
- Assert.Fail(builder.ToString());
- }
- catch (Exception e)
- {
- Type exceptionType = e.GetType();
- if (!IsExpectedException(e))
- {
- throw;
- }
- }
+ Action action = () => sqlCmd.ExecuteNonQuery();
+ Exception exception = Assert.ThrowsAny(action);
+ Assert.Contains(exception.GetType(), ExpectedExceptionTypes);
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
index 0bb9654efc..9bcde64e27 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
@@ -999,27 +999,6 @@ public static TException AssertThrowsWrapper(Action actionThatFails, string[] exceptionMessages, bool innerExceptionMustBeNull = false, Func customExceptionVerifier = null) where TException : Exception
- {
- try
- {
- actionThatFails();
- Assert.Fail("ERROR: Did not get expected exception");
- return null;
- }
- catch (Exception ex)
- {
- foreach (string exceptionMessage in exceptionMessages)
- {
- if ((CheckException(ex, exceptionMessage, innerExceptionMustBeNull)) && ((customExceptionVerifier == null) || (customExceptionVerifier(ex as TException))))
- {
- return (ex as TException);
- }
- }
- throw;
- }
- }
-
public static string GenerateObjectName()
{
return string.Format("TEST_{0}{1}{2}", Environment.GetEnvironmentVariable("ComputerName"), Environment.TickCount, Guid.NewGuid()).Replace('-', '_');
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncCancelledConnectionsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncCancelledConnectionsTest.cs
index 9dd87d8f21..e637015b15 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncCancelledConnectionsTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncCancelledConnectionsTest.cs
@@ -5,6 +5,7 @@
using System;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -140,7 +141,7 @@ private async Task RunCommand(SqlConnection connection, string commandText, bool
Task timeBombTask = null;
try
{
- // Set us up the (time) bomb
+ // Set up us the (time) bomb
if (poison)
{
timeBombTask = TimeBombAsync(command);
@@ -164,10 +165,7 @@ private async Task RunCommand(SqlConnection connection, string commandText, bool
// This looks a little strange, we failed to read above so this should
// fail too. But consider the case where this code is elsewhere (in the
// Dispose method of a class holding this logic)
- while (await reader.NextResultAsync())
- {
- // Discard all results
- }
+ await reader.FlushAllResultsAsync(flushResults: false);
throw;
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTimeoutTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTimeoutTest.cs
index 834157aeec..7ad21e5d41 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTimeoutTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/AsyncTimeoutTest.cs
@@ -166,39 +166,23 @@ private static async Task QueryAndValidate(AsyncAPI api, int index, string delay
case AsyncAPI.ExecuteXmlReaderAsync:
using (XmlReader reader = await cmd.ExecuteXmlReaderAsync().ConfigureAwait(false))
{
- try
- {
- Assert.True(reader.Settings.Async);
- reader.ReadToDescendant("Id");
- result = reader.ReadElementContentAsInt();
- }
- catch (Exception ex)
- {
- Assert.Fail("Exception occurred: " + ex.Message);
- }
+ Assert.NotNull(reader.Settings);
+ Assert.True(reader.Settings.Async);
+
+ reader.ReadToDescendant("Id");
+ result = reader.ReadElementContentAsInt();
}
break;
}
- if (result != index)
- {
- throw new Exception("High Alert! Wrong data received for index: " + index);
- }
- else
- {
- Assert.True(!timeoutExExpected && result == index);
- }
+ Assert.False(timeoutExExpected);
+ Assert.Equal(index, result);
}
catch (SqlException e)
{
- if (!timeoutExExpected)
- {
- throw new Exception("Index " + index + " failed with: " + e.Message);
- }
- else
- {
- Assert.True(timeoutExExpected && e.Class == 11 && e.Number == -2);
- }
+ Assert.True(timeoutExExpected);
+ Assert.Equal(11, e.Class);
+ Assert.Equal(-2, e.Number);
}
finally
{
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/XmlReaderAsyncTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/XmlReaderAsyncTest.cs
index 8be5437b9f..b7811c40ac 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/XmlReaderAsyncTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AsyncTest/XmlReaderAsyncTest.cs
@@ -74,26 +74,15 @@ public static void ExceptionTest()
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
public static async Task MoveToContentAsyncTest()
{
- using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
- using (SqlCommand command = new SqlCommand(CommandText, connection))
- {
- connection.Open();
+ using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString);
+ using SqlCommand command = new SqlCommand(CommandText, connection);
+ connection.Open();
- using (XmlReader xmlReader = await command.ExecuteXmlReaderAsync().ConfigureAwait(false))
- {
- try
- {
- // Issue #781: Test failed here as xmlReader.Settings.Async was set to false
- Assert.True(xmlReader.Settings.Async);
- xmlReader.ReadToDescendant("dbo.Customers");
- Assert.Equal("ALFKI", xmlReader["CustomerID"]);
- }
- catch (Exception ex)
- {
- Assert.Fail("Exception occurred: " + ex.Message);
- }
- }
- }
+ using XmlReader xmlReader = await command.ExecuteXmlReaderAsync().ConfigureAwait(false);
+ // Issue #781: Test failed here as xmlReader.Settings.Async was set to false
+ Assert.True(xmlReader.Settings.Async);
+ xmlReader.ReadToDescendant("dbo.Customers");
+ Assert.Equal("ALFKI", xmlReader["CustomerID"]);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectionBehaviorTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectionBehaviorTest.cs
index 5b108400b0..cce54d9aaf 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectionBehaviorTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectionBehaviorTest.cs
@@ -4,6 +4,7 @@
using System.Data;
using System.Threading.Tasks;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -13,51 +14,43 @@ public class ConnectionBehaviorTest
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
public void ConnectionBehaviorClose()
{
- using (SqlConnection sqlConnection = new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MaxPoolSize = 1 }).ConnectionString))
+ // Arrange
+ SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString) { MaxPoolSize = 1 };
+ using SqlConnection sqlConnection = new SqlConnection(builder.ConnectionString);
+ sqlConnection.Open();
+
+ using SqlCommand command = sqlConnection.CreateCommand();
+ command.CommandText = "SELECT 1";
+
+ // Act
+ using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
- using (SqlCommand command = new SqlCommand("SELECT '1'", sqlConnection))
- {
- sqlConnection.Open();
- using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
- {
- while (reader.Read())
- {
- string result = reader[0].ToString();
- }
- }
-
- Assert.Equal(ConnectionState.Closed, sqlConnection.State);
- }
+ reader.FlushResultSet();
}
+
+ // Assert
+ Assert.Equal(ConnectionState.Closed, sqlConnection.State);
}
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
- public void ConnectionBehaviorCloseAsync()
+ public async Task ConnectionBehaviorCloseAsync()
{
- using (SqlConnection sqlConnection = new SqlConnection((new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) { MaxPoolSize = 1 }).ConnectionString))
- {
- Task result = VerifyConnectionBehaviorCloseAsync(sqlConnection);
- bool value = result.Result;
- }
- }
+ // Arrange
+ SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString) { MaxPoolSize = 1 };
+ using SqlConnection sqlConnection = new SqlConnection(builder.ConnectionString);
+ await sqlConnection.OpenAsync();
- private async Task VerifyConnectionBehaviorCloseAsync(SqlConnection sqlConnection)
- {
- using (SqlCommand command = new SqlCommand("SELECT '1'", sqlConnection))
+ using SqlCommand command = sqlConnection.CreateCommand();
+ command.CommandText = "SELECT 1";
+
+ // Act
+ using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection))
{
- await sqlConnection.OpenAsync();
- using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection))
- {
- while (reader.Read())
- {
- string result = reader[0].ToString();
- }
- }
-
- Assert.Equal(ConnectionState.Closed, sqlConnection.State);
+ await reader.FlushResultSetAsync();
}
- return true;
+ // Assert
+ Assert.Equal(ConnectionState.Closed, sqlConnection.State);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs
index a500055490..0812ea21e2 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs
@@ -84,6 +84,8 @@ public static void EnvironmentHostNameSPIDTest()
// Confirm Server Process Id stays the same after query execution
Assert.Equal(sessionSpid, sqlConnection.ServerProcessId);
}
+
+ // @TODO: Test that *returns* to indicate success is all kinds of messed up.
Assert.Fail("No non-empty hostname found for the application");
}
@@ -305,15 +307,11 @@ public static void ConnectionResiliencySPIDTest()
int clientSPID = conn.ServerProcessId;
int serverSPID = 0;
InternalConnectionWrapper wrapper = new(conn, true, builder.ConnectionString);
+
using SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT @@SPID";
- using (SqlDataReader reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- serverSPID = reader.GetInt16(0);
- }
- }
+
+ serverSPID = (int)cmd.ExecuteScalar()!;
Assert.Equal(serverSPID, clientSPID);
// Also check SPID after query execution
@@ -322,13 +320,7 @@ public static void ConnectionResiliencySPIDTest()
wrapper.KillConnectionByTSql();
// Connection resiliency should reconnect transparently
- using (SqlDataReader reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- serverSPID = reader.GetInt16(0);
- }
- }
+ serverSPID = (int)cmd.ExecuteScalar()!;
// SPID should match server's SPID
Assert.Equal(serverSPID, conn.ServerProcessId);
@@ -426,17 +418,14 @@ public static void ConnectionAliasTest()
{
DataSource = DataTestUtility.AliasName
};
+
using SqlConnection sqlConnection = new(builder.ConnectionString);
+
+ // @TODO: This should be tested in connection string builder tests
Assert.Equal(DataTestUtility.AliasName, builder.DataSource);
- try
- {
- sqlConnection.Open();
- Assert.Equal(ConnectionState.Open, sqlConnection.State);
- }
- catch (SqlException ex)
- {
- Assert.Fail(ex.Message);
- }
+
+ sqlConnection.Open();
+ Assert.Equal(ConnectionState.Open, sqlConnection.State);
}
private static bool CanUseDacConnection()
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderCancellationTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderCancellationTest.cs
index 5199922174..cef8fb2278 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderCancellationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderCancellationTest.cs
@@ -2,15 +2,41 @@
// 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.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
{
public class DataReaderCancellationTest
{
+ // @TODO: Make this a commonly used long running query?
+ // This query generates a billion results by performing a cross join on 10 rows 3 times (1k
+ // records), then cross joining that set 3 times (1b records).
+ private const string LongRunningQuery =
+ @"WITH " +
+ @" TenRows AS ( " +
+ @" SELECT value " +
+ @" FROM ( " +
+ @" VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10) " +
+ @" ) AS TenRows (value) " +
+ @" ), " +
+ @" ThousandRows AS ( " +
+ @" SELECT A.value AS A, B.value AS B, C.value AS C " +
+ @" FROM " +
+ @" TenRows AS A, " +
+ @" TenRows AS B, " +
+ @" TenRows AS C, " +
+ @" ) " +
+ @"SELECT * " +
+ @"FROM " +
+ @" ThousandRows AS A, " +
+ @" ThousandRows AS B, " +
+ @" ThousandRows AS C";
+
///
/// Test ensures cancellation token is registered before ReadAsync starts processing results from TDS Stream,
/// such that when Cancel is triggered, the token is capable of canceling reading further results.
@@ -20,31 +46,37 @@ public class DataReaderCancellationTest
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
public static async Task CancellationTokenIsRespected_ReadAsync()
{
- const string longRunningQuery = @"
-with TenRows as (select Value from (values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) as TenRows (Value)),
- ThousandRows as (select A.Value as A, B.Value as B, C.Value as C from TenRows as A, TenRows as B, TenRows as C)
-select *
-from ThousandRows as A, ThousandRows as B, ThousandRows as C;";
-
- using (var source = new CancellationTokenSource())
- using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ // Arrange
+ using CancellationTokenSource source = new();
+
+ using SqlConnection connection = new(DataTestUtility.TCPConnectionString);
+ await connection.OpenAsync(source.Token);
+
+ // - Set up command that returns millions of rows
+ using SqlCommand command = connection.CreateCommand();
+ command.CommandText = LongRunningQuery;
+
+ // Act
+ Func action = async () =>
{
- await connection.OpenAsync(source.Token);
+ // - Execute query
+ using SqlDataReader reader = await command.ExecuteReaderAsync(source.Token);
- Stopwatch stopwatch = Stopwatch.StartNew();
- await Assert.ThrowsAsync(async () =>
+ // - Cancel after each record is read (should cancel after first record)
+ while (await reader.ReadAsync(source.Token))
{
- using (var command = new SqlCommand(longRunningQuery, connection))
- using (var reader = await command.ExecuteReaderAsync(source.Token))
- {
- while (await reader.ReadAsync(source.Token))
- {
- source.Cancel();
- }
- }
- });
- Assert.True(stopwatch.ElapsedMilliseconds < 10000, "Cancellation did not trigger on time.");
- }
+ source.Cancel();
+ }
+ };
+
+ // Assert
+ // - Action should throw task cancelled exception
+ Stopwatch stopwatch = Stopwatch.StartNew();
+ await Assert.ThrowsAsync(action);
+ stopwatch.Stop();
+
+ // - Ensure exception was thrown within 10 seconds of execution
+ Assert.True(stopwatch.ElapsedMilliseconds < 10000, "Cancellation did not trigger on time");
}
///
@@ -56,30 +88,37 @@ await Assert.ThrowsAsync(async () =>
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
public static async Task CancelledCancellationTokenIsRespected_ReadAsync()
{
- const string longRunningQuery = @"
-with TenRows as (select Value from (values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) as TenRows (Value)),
- ThousandRows as (select A.Value as A, B.Value as B, C.Value as C from TenRows as A, TenRows as B, TenRows as C)
-select *
-from ThousandRows as A, ThousandRows as B, ThousandRows as C;";
-
- using (var source = new CancellationTokenSource())
- using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ // Arrange
+ using CancellationTokenSource source = new();
+
+ using SqlConnection connection = new(DataTestUtility.TCPConnectionString);
+ await connection.OpenAsync(source.Token);
+
+ // - Set up command that returns millions of rows
+ using SqlCommand command = connection.CreateCommand();
+ command.CommandText = LongRunningQuery;
+
+ // Act
+ Func action = async () =>
{
- await connection.OpenAsync(source.Token);
+ // - Execute query
+ using SqlDataReader reader = await command.ExecuteReaderAsync(source.Token);
- Stopwatch stopwatch = Stopwatch.StartNew();
- await Assert.ThrowsAsync(async () =>
- {
- using (var command = new SqlCommand(longRunningQuery, connection))
- using (var reader = await command.ExecuteReaderAsync(source.Token))
- {
- source.Cancel();
- while (await reader.ReadAsync(source.Token))
- { }
- }
- });
- Assert.True(stopwatch.ElapsedMilliseconds < 10000, "Cancellation did not trigger on time.");
- }
+ // - Cancel before reading
+ source.Cancel();
+
+ // - Read all results (should cancel before first record is read)
+ await reader.FlushResultSetAsync(source.Token);
+ };
+
+ // Assert
+ // - Action should throw task cancelled exception
+ Stopwatch stopwatch = Stopwatch.StartNew();
+ await Assert.ThrowsAsync(action);
+ stopwatch.Stop();
+
+ // - Ensure exception was thrown within 10 seconds of execution
+ Assert.True(stopwatch.ElapsedMilliseconds < 10000, "Cancellation did not trigger on time");
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs
index 040119616e..97b15ec25a 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs
@@ -733,16 +733,10 @@ public static async Task CanGetCharsSequentially()
if (await sqlReader.ReadAsync())
{
long id = sqlReader.GetInt64(0);
- if (id != 1)
- {
- Assert.Fail("Id not 1");
- }
+ Assert.Equal(1, id);
var sliced = GetPooledChars(sqlReader, 1, input);
- if (!sliced.SequenceEqual(input.ToCharArray()))
- {
- Assert.Fail("sliced != input");
- }
+ Assert.Equal(input.ToCharArray(), sliced);
}
}
}
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 74423f9f13..61dbd9d594 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataStreamTest/DataStreamTest.cs
@@ -13,6 +13,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
+using Microsoft.Data.SqlClient.Tests.Common;
using Microsoft.Data.SqlClient.TestUtilities;
using Xunit;
using Xunit.Abstractions;
@@ -1215,25 +1216,18 @@ private static void SqlCharsBytesTest(string connectionString)
private static void CloseConnection(string connectionString)
{
- using (SqlConnection conn = new SqlConnection(connectionString))
- {
- conn.Open();
- using (SqlCommand cmd = new SqlCommand("select * from orders where orderid < 10253", conn))
- using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
- {
- DataTestUtility.AssertEqualsWithDescription(ConnectionState.Open, conn.State, "FAILED: Connection should be in open state");
+ using SqlConnection conn = new SqlConnection(connectionString);
+ conn.Open();
- while (reader.Read())
- {
- for (int i = 0; i < reader.FieldCount; i++)
- {
- reader.GetValue(i);
- }
- }
- }
+ using SqlCommand cmd = new SqlCommand("select * from orders where orderid < 10253", conn);
+ using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
+ {
+ DataTestUtility.AssertEqualsWithDescription(ConnectionState.Open, conn.State, "FAILED: Connection should be in open state");
- DataTestUtility.AssertEqualsWithDescription(ConnectionState.Closed, conn.State, "FAILED: Connection should be in closed state after reader close");
+ reader.FlushResultSet();
}
+
+ DataTestUtility.AssertEqualsWithDescription(ConnectionState.Closed, conn.State, "FAILED: Connection should be in closed state after reader close");
}
private static void OpenConnection(string connectionString)
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ExceptionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ExceptionTest.cs
index 4179b7bf4b..637061597a 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ExceptionTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ExceptionTest.cs
@@ -8,6 +8,7 @@
using System.Data;
using System.Globalization;
using System.Threading.Tasks;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -288,6 +289,7 @@ public static void EnclavesConnectionExceptionTest()
}
}
+ // @TODO: Verify this test is doing what we expect it to do.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
public static async Task UnobservedTaskExceptionTest()
{
@@ -308,15 +310,8 @@ public static async Task UnobservedTaskExceptionTest()
{
try
{
- using (var reader = await command.ExecuteReaderAsync())
- {
- do
- {
- while (await reader.ReadAsync())
- {
- }
- } while (await reader.NextResultAsync());
- }
+ using SqlDataReader reader = await command.ExecuteReaderAsync();
+ await reader.FlushAllResultsAsync();
}
catch (SqlException ex)
{
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs
index 03c5f794c0..3b8107d324 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs
@@ -214,10 +214,6 @@ private void BulkCopyData(CommandBehavior cb, bool enableStraming, int expectedT
{
bulkCopy.WriteToServer(reader);
}
- catch (Exception ex)
- {
- Assert.Fail(ex.Message);
- }
finally
{
reader.Close();
@@ -252,10 +248,6 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, in
{
await bulkCopy.WriteToServerAsync(reader);
}
- catch (Exception ex)
- {
- Assert.Fail(ex.Message);
- }
finally
{
reader.Close();
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs
index 69265c4e75..0a2ed2a276 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs
@@ -690,10 +690,6 @@ FROM [{table}] AS [l]
});
}
}
- catch (Exception e)
- {
- Assert.Fail("CRITIAL: Test should not fail randomly. Exception occurred: " + e.Message);
- }
finally
{
using var dropConn = new SqlConnection(DataTestUtility.TCPConnectionString);
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs
index 4574f81a93..72c3ac31bf 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/ParametersTest.cs
@@ -1017,13 +1017,12 @@ private static void RunParameterTest()
{
connection.Close();
}
- if (cm.Parameters["@id2"].Value == null)
- {
- return;
- }
- else if ((Guid)cm.Parameters["@id2"].Value != expectedGuid)
+
+ object id2Value = cm.Parameters["@id2"].Value;
+ if (id2Value is not null)
{
- Assert.Fail("CRITICAL : Unexpected data found in SqlCommand parameters, this is a MAJOR issue.");
+ // Null values are allowed, but if it is not null, the expected guid must be set.
+ Assert.Equal(expectedGuid, (Guid)id2Value);
}
}
}
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 9e7a6612a7..4008567b11 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs
@@ -96,6 +96,7 @@ public void TestConnectionIsSafeToReuse()
{
using SqlConnection connection = new(DataTestUtility.TCPConnectionString);
+ // @TODO: Split into two tests
// Bad Scenario - exception expected.
try
{
@@ -133,7 +134,7 @@ public void TestConnectionIsSafeToReuse()
catch (Exception e)
{
// Ignore this exception as it's deliberately introduced.
- Assert.True(e.Message.Contains("Object reference not set to an instance of an object"), "Expected exception did not occur");
+ Assert.Contains("Object reference not set to an instance of an object", e.Message);
}
// Good Scenario - No failure expected.
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/TestBulkCopyWithUTF8.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/TestBulkCopyWithUTF8.cs
index 5b7112476d..1cd0a69aad 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/TestBulkCopyWithUTF8.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/TestBulkCopyWithUTF8.cs
@@ -104,16 +104,8 @@ public void BulkCopy_Utf8Data_ShouldMatchSource(bool isMarsEnabled, bool enableS
DestinationTableName = s_destinationTable
};
- try
- {
- // Perform bulk copy from source to destination table
- bulkCopy.WriteToServer(reader);
- }
- catch (Exception ex)
- {
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
- }
+ // Perform bulk copy from source to destination table
+ bulkCopy.WriteToServer(reader);
// Verify that the 1 row from the source table has been copied into our destination table.
Assert.Equal(1, Convert.ToInt16(countCommand.ExecuteScalar()));
@@ -167,17 +159,9 @@ public async Task BulkCopy_Utf8Data_ShouldMatchSource_Async(bool isMarsEnabled,
EnableStreaming = enableStreaming,
DestinationTableName = s_destinationTable
};
-
- try
- {
- // Perform bulk copy from source to destination table
- await bulkCopy.WriteToServerAsync(reader);
- }
- catch (Exception ex)
- {
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
- }
+
+ // Perform bulk copy from source to destination table
+ await bulkCopy.WriteToServerAsync(reader);
// Verify that the 1 row from the source table has been copied into our destination table.
Assert.Equal(1, Convert.ToInt16(await countCommand.ExecuteScalarAsync()));
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs
index 9f20521f08..1ca4885ce5 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs
@@ -6,6 +6,7 @@
using System.Data;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -46,80 +47,86 @@ public static void PlainMARSCancelTestNP()
// Synapse: Remove dependency on Northwind database + WAITFOR not supported + ';' not supported
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
- public static void PlainCancelTestAsync()
- {
+ public static Task PlainCancelTestAsync() =>
PlainCancelAsync(tcp_connStr);
- }
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
[PlatformSpecific(TestPlatforms.Windows)]
- public static void PlainCancelTestAsyncNP()
- {
+ public static Task PlainCancelTestAsyncNP() =>
PlainCancelAsync(np_connStr);
- }
// Synapse: Remove dependency from Northwind database + WAITFOR not supported + ';' not supported.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
- public static void PlainMARSCancelTestAsync()
- {
+ public static Task PlainMARSCancelTestAsync() =>
PlainCancelAsync((new SqlConnectionStringBuilder(tcp_connStr) { MultipleActiveResultSets = true }).ConnectionString);
- }
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
[PlatformSpecific(TestPlatforms.Windows)]
- public static void PlainMARSCancelTestAsyncNP()
- {
+ public static Task PlainMARSCancelTestAsyncNP() =>
PlainCancelAsync((new SqlConnectionStringBuilder(np_connStr) { MultipleActiveResultSets = true }).ConnectionString);
- }
private static void PlainCancel(string connString)
{
- using (SqlConnection conn = new SqlConnection(connString))
- using (SqlCommand cmd = new SqlCommand("select * from dbo.Orders; waitfor delay '00:00:10'; select * from dbo.Orders", conn))
+ // Arrange
+ using SqlConnection conn = new SqlConnection(connString);
+ conn.Open();
+
+ using SqlCommand command = conn.CreateCommand();
+ command.CommandText =
+ @"SELECT * FROM dbo.Orders; " +
+ @"WAITFOR DELAY '00:00:10'; " +
+ @"SELECT * FROM dbo.Orders;";
+
+ // Act
+ Action action = () =>
{
- conn.Open();
- using (SqlDataReader reader = cmd.ExecuteReader())
- {
- cmd.Cancel();
- DataTestUtility.AssertThrowsWrapper(
- () =>
- {
- do
- {
- while (reader.Read())
- {
- }
- }
- while (reader.NextResult());
- },
- "A severe error occurred on the current command. The results, if any, should be discarded.");
- }
- }
+ // - Execute reader
+ using SqlDataReader reader = command.ExecuteReader();
+
+ // - Cancel command
+ command.Cancel();
+
+ // - Flush results - should throw
+ reader.FlushAllResults();
+ };
+
+ // Assert
+ SqlException exception = Assert.Throws(action);
+ Assert.Contains(
+ "A severe error occurred on the current command. The results, if any, should be discarded.",
+ exception.Message);
}
- private static void PlainCancelAsync(string connString)
+ private static async Task PlainCancelAsync(string connString)
{
- using (SqlConnection conn = new SqlConnection(connString))
- using (SqlCommand cmd = new SqlCommand("select * from dbo.Orders; waitfor delay '00:00:10'; select * from dbo.Orders", conn))
+ // Arrange
+ using SqlConnection conn = new SqlConnection(connString);
+ conn.Open();
+
+ using SqlCommand command = conn.CreateCommand();
+ command.CommandText =
+ @"SELECT * FROM dbo.Orders; " +
+ @"WAITFOR DELAY '00:00:10'; " +
+ @"SELECT * FROM dbo.Orders;";
+
+ // Act
+ Func action = async () =>
{
- conn.Open();
- Task readerTask = cmd.ExecuteReaderAsync();
- DataTestUtility.AssertThrowsWrapper(
- () =>
- {
- readerTask.Wait(2000);
- SqlDataReader reader = readerTask.Result;
- cmd.Cancel();
- do
- {
- while (reader.Read())
- {
- }
- }
- while (reader.NextResult());
- },
- "A severe error occurred on the current command. The results, if any, should be discarded.");
- }
+ // - Execute reader
+ SqlDataReader reader = await command.ExecuteReaderAsync();
+
+ // - Cancel command
+ command.Cancel();
+
+ // - Flush results - should throw
+ await reader.FlushAllResultsAsync();
+ };
+
+ // Assert
+ SqlException exception = await Assert.ThrowsAsync(action);
+ Assert.Contains(
+ "A severe error occurred on the current command. The results, if any, should be discarded.",
+ exception.Message);
}
// Synapse: Remove dependency from Northwind database + WAITFOR not supported + ';' not supported.
@@ -424,20 +431,16 @@ private static void ExecuteCommandCancelExpected(object state)
string errorMessage = SystemDataResourceManager.Instance.SQL_OperationCancelled;
string errorMessageSevereFailure = SystemDataResourceManager.Instance.SQL_SevereError;
- DataTestUtility.ExpectFailure(() =>
+ Action action = () =>
{
threadsReady.SignalAndWait();
- using (SqlDataReader r = command.ExecuteReader())
- {
- do
- {
- while (r.Read())
- {
- }
- } while (r.NextResult());
- }
- }, new string[] { errorMessage, errorMessageSevereFailure });
+ using SqlDataReader reader = command.ExecuteReader();
+ reader.FlushAllResults();
+ };
+
+ SqlException exception = Assert.Throws(action);
+ Assert.Contains(exception.Message, new[] { errorMessage, errorMessageSevereFailure });
}
private static void CancelSharedCommand(object state)
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs
index c2a4ab79e8..ac73e52b3a 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlDependencyTest/SqlDependencyTest.cs
@@ -115,15 +115,8 @@ public void OnChangeAddHasChanges()
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
public void SqlDependencyStartStopTest()
{
- try
- {
- SqlDependency.Start(DataTestUtility.TCPConnectionString);
- SqlDependency.Stop(DataTestUtility.TCPConnectionString);
- }
- catch (Exception e)
- {
- Assert.Fail(e.Message);
- }
+ SqlDependency.Start(DataTestUtility.TCPConnectionString);
+ SqlDependency.Stop(DataTestUtility.TCPConnectionString);
}
[Fact]
@@ -145,15 +138,8 @@ public void SqlDepdencyStartNullConnectionString_Throws()
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
public void SqlDependencyStartStopDefaultTest()
{
- try
- {
- SqlDependency.Start(DataTestUtility.TCPConnectionString, null);
- SqlDependency.Stop(DataTestUtility.TCPConnectionString, null);
- }
- catch (Exception e)
- {
- Assert.Fail(e.Message);
- }
+ SqlDependency.Start(DataTestUtility.TCPConnectionString, null);
+ SqlDependency.Stop(DataTestUtility.TCPConnectionString, null);
}
[Fact]
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlStatisticsTest/SqlStatisticsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlStatisticsTest/SqlStatisticsTest.cs
index f04bc38a4d..c035532229 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlStatisticsTest/SqlStatisticsTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlStatisticsTest/SqlStatisticsTest.cs
@@ -6,6 +6,7 @@
using System.Data;
using System.Data.Common;
using System.Collections;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -37,11 +38,7 @@ public static void TestRetrieveStatistics()
clientConnectionId = connection.ClientConnectionId;
Assert.True(clientConnectionId != Guid.Empty);
- int row = 0;
- while (dr.Read())
- {
- row++;
- }
+ dr.FlushResultSet();
}
}
// Ensure calling RetrieveStatistics multiple times do not affect the ConnectionTime
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs
index 2ff72bba06..82f5a34a71 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs
@@ -416,25 +416,17 @@ public void TestBulkCopyFromSqlTable(int bulkCopySourceMode)
{
DestinationTableName = s_tableName,
};
-
- try
- {
- switch (bulkCopySourceMode)
- {
- case 1:
- bulkCopy.WriteToServer(reader);
- break;
- case 2:
- bulkCopy.WriteToServer(table);
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(bulkCopySourceMode), $"Unsupported bulk copy source mode: {bulkCopySourceMode}");
- }
- }
- catch (Exception ex)
+
+ switch (bulkCopySourceMode)
{
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
+ case 1:
+ bulkCopy.WriteToServer(reader);
+ break;
+ case 2:
+ bulkCopy.WriteToServer(table);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(bulkCopySourceMode), $"Unsupported bulk copy source mode: {bulkCopySourceMode}");
}
// Verify that the 2 rows from the source table have been copied into the destination table.
@@ -514,25 +506,18 @@ public async Task TestBulkCopyFromSqlTableAsync(int bulkCopySourceMode)
{
DestinationTableName = s_tableName,
};
-
- try
- { // Perform bulkcopy
- switch (bulkCopySourceMode)
- {
- case 1:
- await bulkCopy.WriteToServerAsync(reader);
- break;
- case 2:
- await bulkCopy.WriteToServerAsync(table);
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(bulkCopySourceMode), $"Unsupported bulk copy source mode: {bulkCopySourceMode}");
- }
- }
- catch (Exception ex)
+
+ // Perform bulkcopy
+ switch (bulkCopySourceMode)
{
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
+ case 1:
+ await bulkCopy.WriteToServerAsync(reader);
+ break;
+ case 2:
+ await bulkCopy.WriteToServerAsync(table);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(bulkCopySourceMode), $"Unsupported bulk copy source mode: {bulkCopySourceMode}");
}
// Verify that the 2 rows from the source table have been copied into the destination table.
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/VectorTypeBackwardCompatibilityTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/VectorTypeBackwardCompatibilityTests.cs
index b3f42a5617..33f6109dc8 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/VectorTypeBackwardCompatibilityTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/VectorTypeBackwardCompatibilityTests.cs
@@ -488,17 +488,9 @@ public void TestSqlBulkCopyForVectorAsVarchar()
{
DestinationTableName = s_tableName,
};
-
- try
- {
- // Perform bulk copy from source to destination table
- bulkCopy.WriteToServer(reader);
- }
- catch (Exception ex)
- {
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
- }
+
+ // Perform bulk copy from source to destination table
+ bulkCopy.WriteToServer(reader);
// Verify that the 2 rows from the source table have been copied into the destination table.
Assert.Equal(2, Convert.ToInt16(countCommand.ExecuteScalar()));
@@ -553,17 +545,9 @@ public async Task TestSqlBulkCopyForVectorAsVarcharAsync()
{
DestinationTableName = s_tableName,
};
-
- try
- {
- // Perform bulk copy from source to destination table
- await bulkCopy.WriteToServerAsync(reader);
- }
- catch (Exception ex)
- {
- // If bulk copy fails, fail the test with the exception message
- Assert.Fail($"Bulk copy failed: {ex.Message}");
- }
+
+ // Perform bulk copy from source to destination table
+ await bulkCopy.WriteToServerAsync(reader);
// Verify that the 2 rows from the source table have been copied into the destination table.
Assert.Equal(2, Convert.ToInt16(await countCommand.ExecuteScalarAsync()));
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
index 96108636d0..ee65271ac3 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/DiagnosticTest.cs
@@ -23,6 +23,7 @@
using System.Runtime.CompilerServices;
using System;
using System.Data;
+using Microsoft.Data.SqlClient.Tests.Common;
using Microsoft.DotNet.RemoteExecutor;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -143,10 +144,7 @@ public void ExecuteReaderTest()
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
- while (reader.Read())
- {
- // Read until end.
- }
+ reader.FlushResultSet();
}
}, [WriteConnectionOpenBefore, WriteConnectionOpenAfter, WriteCommandBefore, WriteCommandAfter, WriteConnectionCloseBefore, WriteConnectionCloseAfter]);
return RemoteExecutor.SuccessExitCode;
@@ -190,10 +188,7 @@ public void ExecuteReaderWithCommandBehaviorTest()
conn.Open();
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default);
- while (reader.Read())
- {
- // Read to end
- }
+ reader.FlushResultSet();
}
}, [WriteConnectionOpenBefore, WriteConnectionOpenAfter, WriteCommandBefore, WriteCommandAfter, WriteConnectionCloseBefore, WriteConnectionCloseAfter]);
return RemoteExecutor.SuccessExitCode;
@@ -219,7 +214,7 @@ public void ExecuteXmlReaderTest()
XmlReader reader = cmd.ExecuteXmlReader();
while (reader.Read())
{
- // Read to end
+ // Flush results
}
}
}, [WriteConnectionOpenBefore, WriteConnectionOpenAfter, WriteCommandBefore, WriteCommandAfter, WriteConnectionCloseBefore, WriteConnectionCloseAfter]);
@@ -373,10 +368,7 @@ public void ExecuteReaderAsyncTest()
conn.Open();
SqlDataReader reader = await cmd.ExecuteReaderAsync();
- while (reader.Read())
- {
- // Read to end
- }
+ reader.FlushResultSet();
}
}, [WriteConnectionOpenBefore, WriteConnectionOpenAfter, WriteCommandBefore, WriteCommandAfter, WriteConnectionCloseBefore, WriteConnectionCloseAfter]).Wait();
return RemoteExecutor.SuccessExitCode;
@@ -434,7 +426,7 @@ public void ExecuteXmlReaderAsyncTest()
XmlReader reader = await cmd.ExecuteXmlReaderAsync();
while (reader.Read())
{
- // Read to end
+ // Flush results
}
}
}, [WriteConnectionOpenBefore, WriteConnectionOpenAfter, WriteCommandBefore, WriteCommandAfter, WriteConnectionCloseBefore, WriteConnectionCloseAfter]).Wait();
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventSourceTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventSourceTest.cs
index 4992c55974..df6ca2a37e 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventSourceTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/EventSourceTest.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Linq;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
@@ -18,10 +19,7 @@ public void EventSourceTestAll()
connection.Open();
using SqlCommand command = new("SELECT @@VERSION", connection);
using SqlDataReader reader = command.ExecuteReader();
- while (reader.Read())
- {
- // Flush data
- }
+ reader.FlushResultSet();
}
// Need to investigate better way of validating traces in sequential runs,
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs
index ffd6c8ff79..5381f661ba 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/XEventsTracingTest.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Xml;
using System.Xml.XPath;
+using Microsoft.Data.SqlClient.Tests.Common;
using Xunit;
using Xunit.Abstractions;
@@ -51,10 +52,7 @@ ADD EVENT RPC_STARTING (ACTION (client_connection_id) WHERE (client_connection_i
{
using SqlCommand command = new(query, activityConnection) { CommandType = commandType };
using SqlDataReader reader = command.ExecuteReader();
- while (reader.Read())
- {
- // Flush data
- }
+ reader.FlushResultSet();
ids = TraceListener.ActivityIDs;
}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlErrorCollectionTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlErrorCollectionTests.cs
new file mode 100644
index 0000000000..f9ea12027a
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlErrorCollectionTests.cs
@@ -0,0 +1,241 @@
+// 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;
+using System.Collections.Generic;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.Microsoft.Data.SqlClient
+{
+ public class SqlErrorCollectionTests
+ {
+ private const int ErrorsInTestCollection = 3;
+
+ [Fact]
+ public void Constructor_PropertiesInitialized()
+ {
+ // Act
+ SqlErrorCollection collection = new();
+
+ // Assert
+ Assert.Empty(collection);
+
+ // - ICollection properties
+ ICollection collection2 = collection;
+ Assert.Same(collection2, collection2.SyncRoot);
+ Assert.False(collection2.IsSynchronized);
+ }
+
+ [Theory]
+ [InlineData(1)]
+ [InlineData(2)]
+ [InlineData(10)]
+ public void Add(int itemsToAdd)
+ {
+ // Arrange
+ SqlErrorCollection collection = new();
+ SqlError error = GetTestError();
+
+ // Act
+ for (int i = 0; i < itemsToAdd; i++)
+ {
+ collection.Add(error);
+ }
+
+ // Assert
+ Assert.Equal(itemsToAdd, collection.Count);
+ }
+
+ [Theory]
+ [InlineData(ErrorsInTestCollection, 0)] // Destination just right size
+ [InlineData(ErrorsInTestCollection + 10, 0)] // Null elements at end
+ [InlineData(ErrorsInTestCollection + 2, 2)] // Null elements at beginning
+ [InlineData(ErrorsInTestCollection + 10, 1)] // Null elements at beginning and end
+ public void CopyTo_SqlErrorArray_WithinRange(int destinationSize, int offset)
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] errors) = GetTestErrorCollection();
+ SqlError[] copyDestination = new SqlError[destinationSize];
+
+ // Act
+ // - Uses SqlErrorCollection.CopyTo
+ collection.CopyTo(copyDestination, offset);
+
+ // Assert
+ AssertCopiedCollection(errors, copyDestination, offset);
+ }
+
+ [Theory]
+ [InlineData(ErrorsInTestCollection, -1)] // Offset is negative
+ [InlineData(ErrorsInTestCollection - 1, 0)] // Destination is too small
+ [InlineData(ErrorsInTestCollection, 1)] // Destination is big enough, but offset pushes it over edge
+ public void CopyTo_SqlErrorArray_OutOfRange(int destinationSize, int offset)
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] _) = GetTestErrorCollection();
+ SqlError[] copyDestination = new SqlError[destinationSize];
+
+ // Act
+ // - Uses ICollection.CopyTo
+ Action action = () => collection.CopyTo(copyDestination, offset);
+
+ // Assert
+ Assert.ThrowsAny(action);
+ }
+
+ [Theory]
+ [InlineData(ErrorsInTestCollection, 0)] // Destination just right size
+ [InlineData(ErrorsInTestCollection + 10, 0)] // Null elements at end
+ [InlineData(ErrorsInTestCollection + 2, 2)] // Null elements at beginning
+ [InlineData(ErrorsInTestCollection + 10, 1)] // Null elements at beginning and end
+ public void CopyTo_ObjectArray_WithinRange(int destinationSize, int offset)
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] errors) = GetTestErrorCollection();
+ object[] copyDestination = new object[destinationSize];
+
+ // Act
+ // - Uses ICollection.CopyTo
+ collection.CopyTo(copyDestination, offset);
+
+ // Assert
+ AssertCopiedCollection(errors, copyDestination, offset);
+ }
+
+ [Theory]
+ [InlineData(ErrorsInTestCollection, -1)] // Offset is negative
+ [InlineData(ErrorsInTestCollection - 1, 0)] // Destination is too small
+ [InlineData(ErrorsInTestCollection, 1)] // Destination is big enough, but offset pushes it over edge
+ public void CopyTo_ObjectArray_OutOfRange(int destinationSize, int offset)
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] _) = GetTestErrorCollection();
+ SqlError[] copyDestination = new SqlError[destinationSize];
+
+ // Act
+ // - Uses ICollection.CopyTo
+ Action action = () => collection.CopyTo(copyDestination, offset);
+
+ // Assert
+ Assert.ThrowsAny(action);
+ }
+
+ [Fact]
+ public void CopyTo_ObjectArray_WrongType()
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] errors) = GetTestErrorCollection();
+ int[] destination = new int[errors.Length];
+
+ // Act
+ Action action = () => collection.CopyTo(destination, 0);
+
+ // Assert
+ Assert.Throws(action);
+ }
+
+ [Fact]
+ public void GetEnumerator()
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] errors) = GetTestErrorCollection();
+ List output = new();
+
+ // Act
+ foreach (SqlError error in collection)
+ {
+ output.Add(error);
+ }
+
+ // Assert
+ for (int i = 0; i < errors.Length; i++)
+ {
+ Assert.Same(errors[i], output[i]);
+ }
+ }
+
+ [Theory]
+ [InlineData(0)]
+ [InlineData(1)]
+ [InlineData(2)]
+ public void Indexer_InRange(int index)
+ {
+ // Arrange
+ (SqlErrorCollection collection, SqlError[] errors) = GetTestErrorCollection();
+
+ // Act
+ SqlError result = collection[index];
+
+ // Assert
+ Assert.Same(errors[index], result);
+ }
+
+ [Theory]
+ [InlineData(-1)]
+ [InlineData(123)]
+ public void Indexer_OutOfRange(int index)
+ {
+ // Arrange
+ (SqlErrorCollection collection, _) = GetTestErrorCollection();
+
+ // Act
+ Action action = () => _ = collection[index];
+
+ // Assert
+ Assert.Throws(action);
+ }
+
+ private static void AssertCopiedCollection(SqlError[] source, IReadOnlyList