From e5234068f3be4c59a806af7a89acd3960f4d3e07 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Mon, 14 Oct 2019 11:25:35 +0200 Subject: [PATCH] Fix test for random initialized node The test was using a local method that yielded a single pool while later .Take(50) was requested on this sequence. This always yields an enumeration with 1 element which increases the chances for the assertion to turn false. Rather than relying on Thread.Sleep to create different seeded randoms the StaticConnectionPool now defines a protected constructor that allows one to pass in a seed value. --- .../ConnectionPool/StaticConnectionPool.cs | 18 +++++++++---- .../BuildingBlocks/ConnectionPooling.doc.cs | 27 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs b/src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs index f260ff65445..f58a8c0734b 100644 --- a/src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs +++ b/src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs @@ -15,9 +15,15 @@ public StaticConnectionPool(IEnumerable uris, bool randomize = true, IDateT : this(uris.Select(uri => new Node(uri)), randomize, dateTimeProvider) { } public StaticConnectionPool(IEnumerable nodes, bool randomize = true, IDateTimeProvider dateTimeProvider = null) + : this(nodes, randomize, randomizeSeed: null, dateTimeProvider) { } + + protected StaticConnectionPool(IEnumerable nodes, bool randomize, int? randomizeSeed = null, IDateTimeProvider dateTimeProvider = null) { - nodes.ThrowIfEmpty(nameof(nodes)); Randomize = randomize; + Random = !randomize || !randomizeSeed.HasValue + ? new Random() + : new Random(randomizeSeed.Value); + Initialize(nodes, dateTimeProvider); } @@ -25,17 +31,19 @@ public StaticConnectionPool(IEnumerable nodes, bool randomize = true, IDat //otherwise just manually sort `nodes` before instantiating. protected StaticConnectionPool(IEnumerable nodes, Func nodeScorer, IDateTimeProvider dateTimeProvider = null) { - nodes.ThrowIfEmpty(nameof(nodes)); _nodeScorer = nodeScorer; Initialize(nodes, dateTimeProvider); } private void Initialize(IEnumerable nodes, IDateTimeProvider dateTimeProvider) { + + var nodesProvided = nodes?.ToList() ?? throw new ArgumentNullException(nameof(nodes)); + nodesProvided.ThrowIfEmpty(nameof(nodes)); DateTimeProvider = dateTimeProvider ?? Net.DateTimeProvider.Default; string scheme = null; - foreach (var node in nodes) + foreach (var node in nodesProvided) { if (scheme == null) { @@ -46,7 +54,7 @@ private void Initialize(IEnumerable nodes, IDateTimeProvider dateTimeProvi throw new ArgumentException("Trying to instantiate a connection pool with mixed URI Schemes"); } - InternalNodes = SortNodes(nodes) + InternalNodes = SortNodes(nodesProvided) .DistinctBy(n => n.Uri) .ToList(); LastUpdate = DateTimeProvider.Now(); @@ -87,7 +95,7 @@ protected List AliveNodes protected IDateTimeProvider DateTimeProvider { get; private set; } protected List InternalNodes { get; set; } - protected Random Random { get; } = new Random(); + protected Random Random { get; } protected bool Randomize { get; } /// diff --git a/src/Tests/Tests/ClientConcepts/ConnectionPooling/BuildingBlocks/ConnectionPooling.doc.cs b/src/Tests/Tests/ClientConcepts/ConnectionPooling/BuildingBlocks/ConnectionPooling.doc.cs index b095d90069f..b08738ff166 100644 --- a/src/Tests/Tests/ClientConcepts/ConnectionPooling/BuildingBlocks/ConnectionPooling.doc.cs +++ b/src/Tests/Tests/ClientConcepts/ConnectionPooling/BuildingBlocks/ConnectionPooling.doc.cs @@ -7,6 +7,7 @@ using Elasticsearch.Net; using FluentAssertions; using Nest; +using Tests.Configuration; using Tests.Framework; using Tests.XPack.Security.Privileges; @@ -216,20 +217,30 @@ [U] public void Static() } } + //hide + private class SeededRandomConectionPool : StaticConnectionPool + { + public SeededRandomConectionPool(IEnumerable nodes, int seed) + : base(nodes, randomize: true, randomizeSeed: seed, dateTimeProvider: null) + {} + } + // hide [U] public void RandomizedInitialNodes() { - IEnumerable CreatStaticConnectionPools() + IEnumerable CreateSeededPools(int nodeCount, int pools) { - Thread.Sleep(1); - var uris = Enumerable.Range(1, 50).Select(i => new Uri($"https://10.0.0.{i}:9200/")); - yield return new StaticConnectionPool(uris); + var seed = TestConfiguration.Instance.Seed; + var nodes = Enumerable.Range(1, nodeCount) + .Select(i => new Node(new Uri($"https://10.0.0.{i}:9200/"))) + .ToList(); + for(var i = 0; i < nodeCount; i++) + yield return new SeededRandomConectionPool(nodes, seed + i); } - // assertion works on the probability of seeing a Uri other than https://10.0.0.1:9200/ - // as the first value over 50 runs, when randomized. - CreatStaticConnectionPools() - .Take(50) + var connectionPools = CreateSeededPools(100, 100).ToList(); + connectionPools.Should().HaveCount(100); + connectionPools .Select(p => p.CreateView().First().Uri.ToString()) .All(uri => uri == "https://10.0.0.1:9200/") .Should()