Skip to content

Commit 2a61e83

Browse files
[Release 2.1] Tests | Fix randomly failing tests (#942)
1 parent 97e1dbb commit 2a61e83

File tree

7 files changed

+161
-103
lines changed

7 files changed

+161
-103
lines changed

src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsAlgorithmErrors.cs

+61-52
Large diffs are not rendered by default.

src/Microsoft.Data.SqlClient/tests/FunctionalTests/AlwaysEncryptedTests/ExceptionsCertStore.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,19 @@ public class ExceptionCertFixture : IDisposable
7676

7777
public ExceptionCertFixture()
7878
{
79-
certificate = Utility.CreateCertificate();
79+
if(certificate == null)
80+
{
81+
certificate = Utility.CreateCertificate();
82+
}
8083
thumbprint = certificate.Thumbprint;
8184
certificatePath = string.Format("CurrentUser/My/{0}", thumbprint);
8285
cek = Utility.GenerateRandomBytes(32);
8386
encryptedCek = certStoreProvider.EncryptColumnEncryptionKey(certificatePath, "RSA_OAEP", cek);
8487
#if NET46
85-
masterKeyCertificateNPK = Utility.CreateCertificateWithNoPrivateKey();
88+
if(masterKeyCertificateNPK == null)
89+
{
90+
masterKeyCertificateNPK = Utility.CreateCertificateWithNoPrivateKey();
91+
}
8692
thumbprintNPK = masterKeyCertificateNPK.Thumbprint;
8793
masterKeyPathNPK = "CurrentUser/My/" + thumbprintNPK;
8894
#endif

src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class ConversionTests : IDisposable
2929
private const decimal SmallMoneyMinValue = -214748.3648M;
3030
private const int MaxLength = 10000;
3131
private int NumberOfRows = DataTestUtility.EnclaveEnabled ? 10 : 100;
32-
private readonly X509Certificate2 certificate;
32+
private static X509Certificate2 certificate;
3333
private ColumnMasterKey columnMasterKey;
3434
private ColumnEncryptionKey columnEncryptionKey;
3535
private SqlColumnEncryptionCertificateStoreProvider certStoreProvider = new SqlColumnEncryptionCertificateStoreProvider();
@@ -55,7 +55,10 @@ public ColumnMetaData(SqlDbType columnType, int columnSize, int precision, int s
5555

5656
public ConversionTests()
5757
{
58-
certificate = CertificateUtility.CreateCertificate();
58+
if(certificate == null)
59+
{
60+
certificate = CertificateUtility.CreateCertificate();
61+
}
5962
columnMasterKey = new CspColumnMasterKey(DatabaseHelper.GenerateUniqueName("CMK"), certificate.Thumbprint, certStoreProvider, DataTestUtility.EnclaveEnabled);
6063
databaseObjects.Add(columnMasterKey);
6164

src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/SQLSetupStrategy.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class SQLSetupStrategy : IDisposable
1515
{
1616
internal const string ColumnEncryptionAlgorithmName = @"AEAD_AES_256_CBC_HMAC_SHA256";
1717

18-
protected internal readonly X509Certificate2 certificate;
18+
protected static X509Certificate2 certificate;
1919
public string keyPath { get; internal set; }
2020
public Table ApiTestTable { get; private set; }
2121
public Table BulkCopyAEErrorMessageTestTable { get; private set; }
@@ -56,7 +56,10 @@ public class SQLSetupStrategy : IDisposable
5656

5757
public SQLSetupStrategy()
5858
{
59-
certificate = CertificateUtility.CreateCertificate();
59+
if(certificate == null)
60+
{
61+
certificate = CertificateUtility.CreateCertificate();
62+
}
6063
}
6164

6265
protected SQLSetupStrategy(string customKeyPath) => keyPath = customKeyPath;

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs

+19-10
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ public static void ActiveDirectoryManagedIdentityWithCredentialsMustFail()
369369
Assert.Contains(expectedMessage, e.Message);
370370
}
371371

372-
[ConditionalFact(nameof(IsAADConnStringsSetup))]
372+
[ConditionalFact(nameof(IsAADConnStringsSetup), nameof(IsManagedIdentitySetup))]
373373
public static void ActiveDirectoryManagedIdentityWithPasswordMustFail()
374374
{
375375
// connection fails with expected error message.
@@ -385,7 +385,7 @@ public static void ActiveDirectoryManagedIdentityWithPasswordMustFail()
385385

386386
[InlineData("2445343 2343253")]
387387
[InlineData("2445343$#^@@%2343253")]
388-
[ConditionalTheory(nameof(IsAADConnStringsSetup))]
388+
[ConditionalTheory(nameof(IsAADConnStringsSetup), nameof(IsManagedIdentitySetup))]
389389
public static void ActiveDirectoryManagedIdentityWithInvalidUserIdMustFail(string userId)
390390
{
391391
// connection fails with expected error message.
@@ -444,33 +444,42 @@ public static void ADInteractiveUsingSSPI()
444444
ConnectAndDisconnect(connStr);
445445
}
446446

447+
// Test passes locally everytime, but in pieplines fails randomly with uncertainity.
448+
// e.g. Second AAD connection too slow (802ms)! (More than 30% of the first (576ms).)
449+
[ActiveIssue(16058)]
447450
[ConditionalFact(nameof(IsAADConnStringsSetup))]
448451
public static void ConnectionSpeed()
449452
{
453+
var connString = DataTestUtility.AADPasswordConnectionString;
454+
450455
//Ensure server endpoints are warm
451-
using (var connectionDrill = new SqlConnection(DataTestUtility.AADPasswordConnectionString))
456+
using (var connectionDrill = new SqlConnection(connString))
452457
{
453458
connectionDrill.Open();
454459
}
460+
455461
SqlConnection.ClearAllPools();
462+
ActiveDirectoryAuthenticationProvider.ClearUserTokenCache();
463+
464+
Stopwatch firstConnectionTime = new Stopwatch();
465+
Stopwatch secondConnectionTime = new Stopwatch();
456466

457-
using (var connectionDrill = new SqlConnection(DataTestUtility.AADPasswordConnectionString))
467+
using (var connectionDrill = new SqlConnection(connString))
458468
{
459-
Stopwatch firstConnectionTime = new Stopwatch();
460469
firstConnectionTime.Start();
461470
connectionDrill.Open();
462471
firstConnectionTime.Stop();
463-
using (var connectionDrill2 = new SqlConnection(DataTestUtility.AADPasswordConnectionString))
472+
using (var connectionDrill2 = new SqlConnection(connString))
464473
{
465-
Stopwatch secondConnectionTime = new Stopwatch();
466474
secondConnectionTime.Start();
467475
connectionDrill2.Open();
468476
secondConnectionTime.Stop();
469-
// Subsequent AAD connections within a short timeframe should use an auth token cached from the connection pool
470-
// Second connection speed in tests was typically 10-15% of the first connection time. Using 30% since speeds may vary.
471-
Assert.True(secondConnectionTime.ElapsedMilliseconds / firstConnectionTime.ElapsedMilliseconds < .30, $"Second AAD connection too slow ({secondConnectionTime.ElapsedMilliseconds}ms)! (More than 30% of the first ({firstConnectionTime.ElapsedMilliseconds}ms).)");
472477
}
473478
}
479+
480+
// Subsequent AAD connections within a short timeframe should use an auth token cached from the connection pool
481+
// Second connection speed in tests was typically 10-15% of the first connection time. Using 30% since speeds may vary.
482+
Assert.True(((double)secondConnectionTime.ElapsedMilliseconds / firstConnectionTime.ElapsedMilliseconds) < 0.30, $"Second AAD connection too slow ({secondConnectionTime.ElapsedMilliseconds}ms)! (More than 30% of the first ({firstConnectionTime.ElapsedMilliseconds}ms).)");
474483
}
475484

476485
#region Managed Identity Authentication tests

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ExceptionTest.cs

+16-3
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,25 @@ public static void WarningsBeforeRowsTest()
131131
private static bool CheckThatExceptionsAreDistinctButHaveSameData(SqlException e1, SqlException e2)
132132
{
133133
Assert.True(e1 != e2, "FAILED: verification of exception cloning in subsequent connection attempts");
134-
135134
Assert.False((e1 == null) || (e2 == null), "FAILED: One of exceptions is null, another is not");
136135

137136
bool equal = (e1.Message == e2.Message) && (e1.HelpLink == e2.HelpLink) && (e1.InnerException == e2.InnerException)
138-
&& (e1.Source == e2.Source) && (e1.Data.Count == e2.Data.Count) && (e1.Errors == e2.Errors);
137+
&& (e1.Source == e2.Source) && (e1.Data.Count == e2.Data.Count) && (e1.Errors.Count == e2.Errors.Count);
138+
139+
for (int i = 0; i < e1.Errors.Count; i++)
140+
{
141+
equal = e1.Errors[i].Number == e2.Errors[i].Number
142+
&& e1.Errors[i].Message == e2.Errors[i].Message
143+
&& e1.Errors[i].LineNumber == e2.Errors[i].LineNumber
144+
&& e1.Errors[i].State == e2.Errors[i].State
145+
&& e1.Errors[i].Class == e2.Errors[i].Class
146+
&& e1.Errors[i].Server == e2.Errors[i].Server
147+
&& e1.Errors[i].Procedure == e2.Errors[i].Procedure
148+
&& e1.Errors[i].Source == e2.Errors[i].Source;
149+
if (!equal)
150+
break;
151+
}
152+
139153
IDictionaryEnumerator enum1 = e1.Data.GetEnumerator();
140154
IDictionaryEnumerator enum2 = e2.Data.GetEnumerator();
141155
while (equal)
@@ -147,7 +161,6 @@ private static bool CheckThatExceptionsAreDistinctButHaveSameData(SqlException e
147161
}
148162

149163
Assert.True(equal, string.Format("FAILED: exceptions do not contain the same data (besides call stack):\nFirst: {0}\nSecond: {1}\n", e1, e2));
150-
151164
return true;
152165
}
153166

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest.cs

+47-32
Original file line numberDiff line numberDiff line change
@@ -242,48 +242,63 @@ public void NullTest()
242242
p.UdtTypeName = "Utf8String";
243243
p.Value = DBNull.Value;
244244

245-
using (SqlTransaction trans = conn.BeginTransaction())
245+
bool rerun = false;
246+
do
246247
{
247-
com.Transaction = trans;
248-
using (SqlDataReader reader = com.ExecuteReader())
248+
try
249249
{
250-
251-
Utf8String[] expectedValues = {
252-
new Utf8String("this"),
253-
new Utf8String("is"),
254-
new Utf8String("a"),
255-
new Utf8String("test")
256-
};
257-
258-
int currentValue = 0;
259-
do
250+
using (SqlTransaction trans = conn.BeginTransaction())
260251
{
261-
while (reader.Read())
252+
com.Transaction = trans;
253+
using (SqlDataReader reader = com.ExecuteReader())
262254
{
263-
DataTestUtility.AssertEqualsWithDescription(1, reader.FieldCount, "Unexpected FieldCount.");
264-
if (currentValue < expectedValues.Length)
255+
Utf8String[] expectedValues = {
256+
new Utf8String("this"),
257+
new Utf8String("is"),
258+
new Utf8String("a"),
259+
new Utf8String("test")
260+
};
261+
262+
int currentValue = 0;
263+
do
265264
{
266-
DataTestUtility.AssertEqualsWithDescription(expectedValues[currentValue], reader.GetValue(0), "Unexpected Value.");
267-
DataTestUtility.AssertEqualsWithDescription(expectedValues[currentValue], reader.GetSqlValue(0), "Unexpected SQL Value.");
268-
}
269-
else
270-
{
271-
DataTestUtility.AssertEqualsWithDescription(DBNull.Value, reader.GetValue(0), "Unexpected Value.");
272-
273-
Utf8String sqlValue = (Utf8String)reader.GetSqlValue(0);
274-
INullable iface = sqlValue as INullable;
275-
Assert.True(iface != null, "Expected interface cast to return a non-null value.");
276-
Assert.True(iface.IsNull, "Expected interface cast to have IsNull==true.");
265+
while (reader.Read())
266+
{
267+
DataTestUtility.AssertEqualsWithDescription(1, reader.FieldCount, "Unexpected FieldCount.");
268+
if (currentValue < expectedValues.Length)
269+
{
270+
DataTestUtility.AssertEqualsWithDescription(expectedValues[currentValue], reader.GetValue(0), "Unexpected Value.");
271+
DataTestUtility.AssertEqualsWithDescription(expectedValues[currentValue], reader.GetSqlValue(0), "Unexpected SQL Value.");
272+
}
273+
else
274+
{
275+
DataTestUtility.AssertEqualsWithDescription(DBNull.Value, reader.GetValue(0), "Unexpected Value.");
276+
277+
Utf8String sqlValue = (Utf8String)reader.GetSqlValue(0);
278+
INullable iface = sqlValue as INullable;
279+
Assert.True(iface != null, "Expected interface cast to return a non-null value.");
280+
Assert.True(iface.IsNull, "Expected interface cast to have IsNull==true.");
281+
}
282+
283+
currentValue++;
284+
Assert.True(currentValue <= (expectedValues.Length + 1), "Expected to only hit one extra result.");
285+
}
277286
}
278-
279-
currentValue++;
280-
Assert.True(currentValue <= (expectedValues.Length + 1), "Expected to only hit one extra result.");
287+
while (reader.NextResult());
288+
DataTestUtility.AssertEqualsWithDescription(currentValue, (expectedValues.Length + 1), "Did not hit all expected values.");
289+
rerun = false;
281290
}
282291
}
283-
while (reader.NextResult());
284-
DataTestUtility.AssertEqualsWithDescription(currentValue, (expectedValues.Length + 1), "Did not hit all expected values.");
292+
}
293+
catch (SqlException e)
294+
{
295+
if(e.Message.Contains("Rerun the transaction"))
296+
rerun = true;
297+
else
298+
throw e;
285299
}
286300
}
301+
while(rerun);
287302
}
288303
}
289304
}

0 commit comments

Comments
 (0)