From 213ab54f8afc4adac43bba940e9a86c40e54dba1 Mon Sep 17 00:00:00 2001 From: Max Ewing Date: Tue, 29 Jun 2021 19:26:28 +0100 Subject: [PATCH] fix: users for alias not balanced across threads (#90) This is required due to the fact that, if tests are running with process or AppDomain isolation, all of the tests will enumerate through the users in the same order. Shuffling the enumerators is an approximation that saves having to find a way to synchronise between AppDomains or processes. --- .../Configuration/TestConfiguration.cs | 10 ++++-- .../Extensions/IListExtensions.cs | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 bindings/src/Capgemini.PowerApps.SpecFlowBindings/Extensions/IListExtensions.cs diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs index c4121dd..2534264 100644 --- a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Configuration/TestConfiguration.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Configuration; using System.Linq; + using Capgemini.PowerApps.SpecFlowBindings.Extensions; using YamlDotNet.Serialization; /// @@ -82,7 +83,7 @@ private Dictionary> UserEnumerators .Distinct() .ToDictionary( alias => alias, - alias => this.Users.Where(u => u.Alias == alias).GetEnumerator()); + alias => this.GetUserEnumerator(alias)); } } @@ -119,7 +120,7 @@ public UserConfiguration GetUser(string userAlias, bool useCurrentUser = true) var aliasEnumerator = this.UserEnumerators[userAlias]; if (!aliasEnumerator.MoveNext()) { - this.UserEnumerators[userAlias] = this.Users.Where(u => u.Alias == userAlias).GetEnumerator(); + this.UserEnumerators[userAlias] = this.GetUserEnumerator(userAlias); aliasEnumerator = this.UserEnumerators[userAlias]; aliasEnumerator.MoveNext(); } @@ -149,5 +150,10 @@ internal void Flush() { CurrentUsers.Clear(); } + + private IEnumerator GetUserEnumerator(string alias) + { + return this.Users.Where(u => u.Alias == alias).ToList().Shuffle().GetEnumerator(); + } } } diff --git a/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Extensions/IListExtensions.cs b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Extensions/IListExtensions.cs new file mode 100644 index 0000000..87e424c --- /dev/null +++ b/bindings/src/Capgemini.PowerApps.SpecFlowBindings/Extensions/IListExtensions.cs @@ -0,0 +1,35 @@ +namespace Capgemini.PowerApps.SpecFlowBindings.Extensions +{ + using System; + using System.Collections.Generic; + + /// + /// Extensions for . + /// + internal static class IListExtensions + { + private static readonly Random Rand = new Random(); + + /// + /// Randomises the order of a list. + /// + /// The type of list items. + /// The list. + /// The shuffled list. + internal static IList Shuffle(this IList list) + { + var n = list.Count; + + while (n > 1) + { + n--; + var k = Rand.Next(n + 1); + T value = list[k]; + list[k] = list[n]; + list[n] = value; + } + + return list; + } + } +}