Cleanup of peer connection helpers. Adds peer download helpers.
This commit is contained in:
parent
ab7a334987
commit
1016f568b8
|
@ -1,4 +1,5 @@
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
|
using DistTestCore.Helpers;
|
||||||
using DistTestCore.Logs;
|
using DistTestCore.Logs;
|
||||||
using DistTestCore.Marketplace;
|
using DistTestCore.Marketplace;
|
||||||
using DistTestCore.Metrics;
|
using DistTestCore.Metrics;
|
||||||
|
@ -25,8 +26,14 @@ namespace DistTestCore
|
||||||
testAssemblies = assemblies.Where(a => a.FullName!.ToLowerInvariant().Contains("test")).ToArray();
|
testAssemblies = assemblies.Where(a => a.FullName!.ToLowerInvariant().Contains("test")).ToArray();
|
||||||
|
|
||||||
fixtureLog = new FixtureLog(configuration.GetLogConfig());
|
fixtureLog = new FixtureLog(configuration.GetLogConfig());
|
||||||
|
|
||||||
|
PeerConnectionTestHelpers = new PeerConnectionTestHelpers(this);
|
||||||
|
PeerDownloadTestHelpers = new PeerDownloadTestHelpers(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PeerConnectionTestHelpers PeerConnectionTestHelpers { get; }
|
||||||
|
public PeerDownloadTestHelpers PeerDownloadTestHelpers { get; }
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
public void GlobalSetup()
|
public void GlobalSetup()
|
||||||
{
|
{
|
||||||
|
@ -85,6 +92,17 @@ namespace DistTestCore
|
||||||
return Get().FileManager.GenerateTestFile(size);
|
return Get().FileManager.GenerateTestFile(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Any test files generated in 'action' will be deleted after it returns.
|
||||||
|
/// This helps prevent large tests from filling up discs.
|
||||||
|
/// </summary>
|
||||||
|
public void ScopedTestFiles(Action action)
|
||||||
|
{
|
||||||
|
Get().FileManager.PushFileSet();
|
||||||
|
action();
|
||||||
|
Get().FileManager.PopFileSet();
|
||||||
|
}
|
||||||
|
|
||||||
public IOnlineCodexNode SetupCodexBootstrapNode()
|
public IOnlineCodexNode SetupCodexBootstrapNode()
|
||||||
{
|
{
|
||||||
return SetupCodexBootstrapNode(s => { });
|
return SetupCodexBootstrapNode(s => { });
|
||||||
|
@ -133,18 +151,18 @@ namespace DistTestCore
|
||||||
return Get().CodexStarter.RunningGroups.SelectMany(g => g.Nodes);
|
return Get().CodexStarter.RunningGroups.SelectMany(g => g.Nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BaseLog GetTestLog()
|
public BaseLog GetTestLog()
|
||||||
{
|
{
|
||||||
return Get().Log;
|
return Get().Log;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Log(string msg)
|
public void Log(string msg)
|
||||||
{
|
{
|
||||||
TestContext.Progress.WriteLine(msg);
|
TestContext.Progress.WriteLine(msg);
|
||||||
GetTestLog().Log(msg);
|
GetTestLog().Log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Debug(string msg)
|
public void Debug(string msg)
|
||||||
{
|
{
|
||||||
TestContext.Progress.WriteLine(msg);
|
TestContext.Progress.WriteLine(msg);
|
||||||
GetTestLog().Debug(msg);
|
GetTestLog().Debug(msg);
|
||||||
|
|
|
@ -9,6 +9,8 @@ namespace DistTestCore
|
||||||
TestFile CreateEmptyTestFile();
|
TestFile CreateEmptyTestFile();
|
||||||
TestFile GenerateTestFile(ByteSize size);
|
TestFile GenerateTestFile(ByteSize size);
|
||||||
void DeleteAllTestFiles();
|
void DeleteAllTestFiles();
|
||||||
|
void PushFileSet();
|
||||||
|
void PopFileSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileManager : IFileManager
|
public class FileManager : IFileManager
|
||||||
|
@ -18,6 +20,7 @@ namespace DistTestCore
|
||||||
private readonly Random random = new Random();
|
private readonly Random random = new Random();
|
||||||
private readonly TestLog log;
|
private readonly TestLog log;
|
||||||
private readonly string folder;
|
private readonly string folder;
|
||||||
|
private readonly List<List<TestFile>> fileSetStack = new List<List<TestFile>>();
|
||||||
|
|
||||||
public FileManager(TestLog log, Configuration configuration)
|
public FileManager(TestLog log, Configuration configuration)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +34,7 @@ namespace DistTestCore
|
||||||
{
|
{
|
||||||
var result = new TestFile(Path.Combine(folder, Guid.NewGuid().ToString() + "_test.bin"));
|
var result = new TestFile(Path.Combine(folder, Guid.NewGuid().ToString() + "_test.bin"));
|
||||||
File.Create(result.Filename).Close();
|
File.Create(result.Filename).Close();
|
||||||
|
if (fileSetStack.Any()) fileSetStack.Last().Add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +51,27 @@ namespace DistTestCore
|
||||||
DeleteDirectory();
|
DeleteDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PushFileSet()
|
||||||
|
{
|
||||||
|
fileSetStack.Add(new List<TestFile>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PopFileSet()
|
||||||
|
{
|
||||||
|
if (!fileSetStack.Any()) return;
|
||||||
|
var pop = fileSetStack.Last();
|
||||||
|
fileSetStack.Remove(pop);
|
||||||
|
|
||||||
|
foreach (var file in pop)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(file.Filename);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void GenerateFileBytes(TestFile result, ByteSize size)
|
private void GenerateFileBytes(TestFile result, ByteSize size)
|
||||||
{
|
{
|
||||||
long bytesLeft = size.SizeInBytes;
|
long bytesLeft = size.SizeInBytes;
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
using DistTestCore;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Logging;
|
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
namespace Tests.PeerDiscoveryTests
|
namespace DistTestCore.Helpers
|
||||||
{
|
{
|
||||||
public static class PeerTestHelpers
|
public class PeerConnectionTestHelpers
|
||||||
{
|
{
|
||||||
private static readonly Random random = new Random();
|
private readonly Random random = new Random();
|
||||||
|
private readonly DistTest test;
|
||||||
|
|
||||||
public static void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes, BaseLog? log = null)
|
public PeerConnectionTestHelpers(DistTest test)
|
||||||
{
|
{
|
||||||
AssertFullyConnected(log, nodes.ToArray());
|
this.test = test;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AssertFullyConnected(BaseLog? log = null, params IOnlineCodexNode[] nodes)
|
public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes)
|
||||||
|
{
|
||||||
|
AssertFullyConnected(nodes.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssertFullyConnected(params IOnlineCodexNode[] nodes)
|
||||||
{
|
{
|
||||||
var entries = CreateEntries(nodes);
|
var entries = CreateEntries(nodes);
|
||||||
var pairs = CreatePairs(entries);
|
var pairs = CreatePairs(entries);
|
||||||
|
|
||||||
RetryWhilePairs(pairs, () =>
|
RetryWhilePairs(pairs, () =>
|
||||||
{
|
{
|
||||||
CheckAndRemoveSuccessful(pairs, log);
|
CheckAndRemoveSuccessful(pairs);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (pairs.Any())
|
if (pairs.Any())
|
||||||
|
@ -34,7 +38,7 @@ namespace Tests.PeerDiscoveryTests
|
||||||
private static void RetryWhilePairs(List<Pair> pairs, Action action)
|
private static void RetryWhilePairs(List<Pair> pairs, Action action)
|
||||||
{
|
{
|
||||||
var timeout = DateTime.UtcNow + TimeSpan.FromMinutes(5);
|
var timeout = DateTime.UtcNow + TimeSpan.FromMinutes(5);
|
||||||
while (pairs.Any() && (timeout > DateTime.UtcNow))
|
while (pairs.Any() && timeout > DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
action();
|
action();
|
||||||
|
|
||||||
|
@ -42,15 +46,21 @@ namespace Tests.PeerDiscoveryTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckAndRemoveSuccessful(List<Pair> pairs, BaseLog? log)
|
private void CheckAndRemoveSuccessful(List<Pair> pairs)
|
||||||
{
|
{
|
||||||
var checkTasks = pairs.Select(p => Task.Run(p.Check)).ToArray();
|
var checkTasks = pairs.Select(p => Task.Run(() =>
|
||||||
|
{
|
||||||
|
ApplyRandomDelay();
|
||||||
|
p.Check();
|
||||||
|
})).ToArray();
|
||||||
|
|
||||||
Task.WaitAll(checkTasks);
|
Task.WaitAll(checkTasks);
|
||||||
|
|
||||||
foreach (var pair in pairs.ToArray())
|
foreach (var pair in pairs.ToArray())
|
||||||
{
|
{
|
||||||
if (pair.Success)
|
if (pair.Success)
|
||||||
{
|
{
|
||||||
|
test.Debug(pair.GetMessage());
|
||||||
pairs.Remove(pair);
|
pairs.Remove(pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,6 +96,12 @@ namespace Tests.PeerDiscoveryTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ApplyRandomDelay()
|
||||||
|
{
|
||||||
|
// Calling all the nodes all at the same time is not exactly nice.
|
||||||
|
Time.Sleep(TimeSpan.FromMicroseconds(random.Next(10, 100)));
|
||||||
|
}
|
||||||
|
|
||||||
public class Entry
|
public class Entry
|
||||||
{
|
{
|
||||||
public Entry(IOnlineCodexNode node)
|
public Entry(IOnlineCodexNode node)
|
||||||
|
@ -94,7 +110,7 @@ namespace Tests.PeerDiscoveryTests
|
||||||
Response = node.GetDebugInfo();
|
Response = node.GetDebugInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOnlineCodexNode Node { get ; }
|
public IOnlineCodexNode Node { get; }
|
||||||
public CodexDebugResponse Response { get; }
|
public CodexDebugResponse Response { get; }
|
||||||
|
|
||||||
public IEnumerable<string> GetInCorrectDiscoveryEndpoints(Entry[] allEntries)
|
public IEnumerable<string> GetInCorrectDiscoveryEndpoints(Entry[] allEntries)
|
||||||
|
@ -141,7 +157,6 @@ namespace Tests.PeerDiscoveryTests
|
||||||
|
|
||||||
public void Check()
|
public void Check()
|
||||||
{
|
{
|
||||||
ApplyRandomDelay();
|
|
||||||
aToBTime = Measure(() => AKnowsB = Knows(A, B));
|
aToBTime = Measure(() => AKnowsB = Knows(A, B));
|
||||||
bToATime = Measure(() => BKnowsA = Knows(B, A));
|
bToATime = Measure(() => BKnowsA = Knows(B, A));
|
||||||
}
|
}
|
||||||
|
@ -179,12 +194,6 @@ namespace Tests.PeerDiscoveryTests
|
||||||
return $" ({aName}->{bName}: {aToBTime.TotalMinutes} seconds, {bName}->{aName}: {bToATime.TotalSeconds} seconds)";
|
return $" ({aName}->{bName}: {aToBTime.TotalMinutes} seconds, {bName}->{aName}: {bToATime.TotalSeconds} seconds)";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplyRandomDelay()
|
|
||||||
{
|
|
||||||
// Calling all the nodes all at the same time is not exactly nice.
|
|
||||||
Time.Sleep(TimeSpan.FromMicroseconds(random.Next(10, 100)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TimeSpan Measure(Action action)
|
private static TimeSpan Measure(Action action)
|
||||||
{
|
{
|
||||||
var start = DateTime.UtcNow;
|
var start = DateTime.UtcNow;
|
|
@ -0,0 +1,49 @@
|
||||||
|
namespace DistTestCore.Helpers
|
||||||
|
{
|
||||||
|
public class PeerDownloadTestHelpers
|
||||||
|
{
|
||||||
|
private readonly DistTest test;
|
||||||
|
|
||||||
|
public PeerDownloadTestHelpers(DistTest test)
|
||||||
|
{
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssertFullDownloadInterconnectivity(IEnumerable<IOnlineCodexNode> nodes)
|
||||||
|
{
|
||||||
|
AssertFullDownloadInterconnectivity(nodes, 1.MB());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssertFullDownloadInterconnectivity(IEnumerable<IOnlineCodexNode> nodes, ByteSize testFileSize)
|
||||||
|
{
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
var uploader = node;
|
||||||
|
var downloaders = nodes.Where(n => n != uploader).ToArray();
|
||||||
|
|
||||||
|
test.ScopedTestFiles(() =>
|
||||||
|
{
|
||||||
|
PerformTest(uploader, downloaders);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders)
|
||||||
|
{
|
||||||
|
// 1 test file per downloader.
|
||||||
|
var files = downloaders.Select(d => test.GenerateTestFile(1.MB())).ToArray();
|
||||||
|
|
||||||
|
// Upload all the test files to the uploader.
|
||||||
|
var contentIds = files.Select(uploader.UploadFile).ToArray();
|
||||||
|
|
||||||
|
// Each downloader should retrieve its own test file.
|
||||||
|
for (var i = 0; i < downloaders.Length; i++)
|
||||||
|
{
|
||||||
|
var expectedFile = files[i];
|
||||||
|
var downloadedFile = downloaders[i].DownloadContent(contentIds[i]);
|
||||||
|
|
||||||
|
expectedFile.AssertIsEqual(downloadedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using DistTestCore;
|
using DistTestCore;
|
||||||
|
using DistTestCore.Helpers;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ namespace Tests.PeerDiscoveryTests
|
||||||
|
|
||||||
private void AssertAllNodesConnected()
|
private void AssertAllNodesConnected()
|
||||||
{
|
{
|
||||||
PeerTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes(), GetTestLog());
|
PeerConnectionTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using DistTestCore;
|
using DistTestCore;
|
||||||
using DistTestCore.Codex;
|
using DistTestCore.Codex;
|
||||||
|
using DistTestCore.Helpers;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ namespace Tests.PeerDiscoveryTests
|
||||||
|
|
||||||
private void AssertAllNodesConnected()
|
private void AssertAllNodesConnected()
|
||||||
{
|
{
|
||||||
PeerTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes(), GetTestLog());
|
PeerConnectionTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue