From 455181dbb4a401fc321d93d6dd30f6d89f97514b Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 8 Mar 2021 12:31:17 +1100 Subject: [PATCH] Fixing tests --- .../SqlSyntax/SqlServerSyntaxProvider.cs | 30 ++++++++++++++++++- .../Services/ThreadSafetyServiceTest.cs | 16 ++++++---- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs index 58a283a142..279ab1215f 100644 --- a/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs +++ b/src/Umbraco.Infrastructure/Persistence/SqlSyntax/SqlServerSyntaxProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; @@ -263,10 +263,22 @@ where tbl.[name]=@0 and col.[name]=@1;", tableName, columnName) public void WriteLock(IDatabase db, TimeSpan timeout, params int[] lockIds) { + if (db is null) + { + throw new ArgumentNullException(nameof(db)); + } + + if (db.Transaction is null) + { + throw new ArgumentException(nameof(db) + "." + nameof(db.Transaction) + " is null"); + } + // soon as we get Database, a transaction is started if (db.Transaction.IsolationLevel < IsolationLevel.ReadCommitted) + { throw new InvalidOperationException("A transaction with minimum ReadCommitted isolation level is required."); + } // *not* using a unique 'WHERE IN' query here because the *order* of lockIds is important to avoid deadlocks @@ -275,24 +287,40 @@ where tbl.[name]=@0 and col.[name]=@1;", tableName, columnName) db.Execute($"SET LOCK_TIMEOUT {timeout.TotalMilliseconds};"); var i = db.Execute(@"UPDATE umbracoLock WITH (REPEATABLEREAD) SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id", new { id = lockId }); if (i == 0) // ensure we are actually locking! + { throw new ArgumentException($"LockObject with id={lockId} does not exist."); + } } } public override void ReadLock(IDatabase db, params int[] lockIds) { + if (db is null) + { + throw new ArgumentNullException(nameof(db)); + } + + if (db.Transaction is null) + { + throw new ArgumentException(nameof(db) + "." + nameof(db.Transaction) + " is null"); + } + // soon as we get Database, a transaction is started if (db.Transaction.IsolationLevel < IsolationLevel.ReadCommitted) + { throw new InvalidOperationException("A transaction with minimum ReadCommitted isolation level is required."); + } // *not* using a unique 'WHERE IN' query here because the *order* of lockIds is important to avoid deadlocks foreach (var lockId in lockIds) { var i = db.ExecuteScalar("SELECT value FROM umbracoLock WITH (REPEATABLEREAD) WHERE id=@id", new { id = lockId }); if (i == null) // ensure we are actually locking! + { throw new ArgumentException($"LockObject with id={lockId} does not exist.", nameof(lockIds)); + } } } diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs index cc061c0a18..557035a1e0 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ThreadSafetyServiceTest.cs @@ -147,9 +147,12 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services threads.Add(t); } - // start all threads - log.LogInformation("Starting threads"); - threads.ForEach(x => x.Start()); + using (ExecutionContext.SuppressFlow()) + { + // start all threads + log.LogInformation("Starting threads"); + threads.ForEach(x => x.Start()); + } // wait for all to complete log.LogInformation("Joining threads"); @@ -221,8 +224,11 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services threads.Add(t); } - // start all threads - threads.ForEach(x => x.Start()); + using (ExecutionContext.SuppressFlow()) + { + // start all threads + threads.ForEach(x => x.Start()); + } // wait for all to complete threads.ForEach(x => x.Join());