From 10a0ac33117f2aa4e4fb65f296e89aff65b4963d Mon Sep 17 00:00:00 2001 From: benbierens Date: Sun, 4 Jun 2023 08:59:51 +0200 Subject: [PATCH 1/9] Splits up download tests from connectivity tests and improves testfile logging --- DistTestCore/Codex/CodexContainerRecipe.cs | 10 +++--- DistTestCore/DistTest.cs | 4 +-- DistTestCore/FileManager.cs | 34 ++++++++++++++----- .../Helpers/PeerDownloadTestHelpers.cs | 14 ++++++-- DistTestCore/OnlineCodexNode.cs | 11 +++--- .../FullyConnectedDownloadTests.cs | 19 +++++++++++ .../LayeredDiscoveryTests.cs | 1 - .../PeerDiscoveryTests/PeerDiscoveryTests.cs | 1 - 8 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs diff --git a/DistTestCore/Codex/CodexContainerRecipe.cs b/DistTestCore/Codex/CodexContainerRecipe.cs index e92c93c..5b25a2f 100644 --- a/DistTestCore/Codex/CodexContainerRecipe.cs +++ b/DistTestCore/Codex/CodexContainerRecipe.cs @@ -5,12 +5,12 @@ namespace DistTestCore.Codex { public class CodexContainerRecipe : ContainerRecipeFactory { - #if Arm64 +#if Arm64 public const string DockerImage = "codexstorage/nim-codex:sha-7b88ea0"; - #else - //public const string DockerImage = "codexstorage/nim-codex:sha-7b88ea0"; - public const string DockerImage = "codexstorage/nim-codex:sha-7b88ea0"; - #endif +#else + public const string DockerImage = "thatbenbierens/nim-codex:dhting"; + //public const string DockerImage = "codexstorage/nim-codex:sha-7b88ea0"; +#endif public const string MetricsPortTag = "metrics_port"; public const string DiscoveryPortTag = "discovery-port"; diff --git a/DistTestCore/DistTest.cs b/DistTestCore/DistTest.cs index bf4d59f..df345e8 100644 --- a/DistTestCore/DistTest.cs +++ b/DistTestCore/DistTest.cs @@ -87,9 +87,9 @@ namespace DistTestCore } } - public TestFile GenerateTestFile(ByteSize size) + public TestFile GenerateTestFile(ByteSize size, string label = "") { - return Get().FileManager.GenerateTestFile(size); + return Get().FileManager.GenerateTestFile(size, label); } /// diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index 97cf27c..62b5ba7 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -6,8 +6,8 @@ namespace DistTestCore { public interface IFileManager { - TestFile CreateEmptyTestFile(); - TestFile GenerateTestFile(ByteSize size); + TestFile CreateEmptyTestFile(string label = ""); + TestFile GenerateTestFile(ByteSize size, string label = ""); void DeleteAllTestFiles(); void PushFileSet(); void PopFileSet(); @@ -30,19 +30,20 @@ namespace DistTestCore this.log = log; } - public TestFile CreateEmptyTestFile() + public TestFile CreateEmptyTestFile(string label = "") { - var result = new TestFile(Path.Combine(folder, Guid.NewGuid().ToString() + "_test.bin")); + var path = Path.Combine(folder, Guid.NewGuid().ToString() + "_test.bin"); + var result = new TestFile(log, path, label); File.Create(result.Filename).Close(); if (fileSetStack.Any()) fileSetStack.Last().Add(result); return result; } - public TestFile GenerateTestFile(ByteSize size) + public TestFile GenerateTestFile(ByteSize size, string label) { - var result = CreateEmptyTestFile(); + var result = CreateEmptyTestFile(label); GenerateFileBytes(result, size); - log.Log($"Generated {size.SizeInBytes} bytes of content for file '{result.Filename}'."); + log.Log($"Generated {size.SizeInBytes} bytes of content for file '{result.Describe()}'."); return result; } @@ -104,12 +105,17 @@ namespace DistTestCore public class TestFile { - public TestFile(string filename) + private readonly TestLog log; + + public TestFile(TestLog log, string filename, string label) { + this.log = log; Filename = filename; + Label = label; } public string Filename { get; } + public string Label { get; } public long GetFileSize() { @@ -138,10 +144,20 @@ namespace DistTestCore readExpected = streamExpected.Read(bytesExpected, 0, FileManager.ChunkSize); readActual = streamActual.Read(bytesActual, 0, FileManager.ChunkSize); - if (readExpected == 0 && readActual == 0) return; + if (readExpected == 0 && readActual == 0) + { + log.Log($"OK: '{Describe()}' is equal to '{actual.Describe()}'."); + return; + } Assert.That(readActual, Is.EqualTo(readExpected), "Unable to read buffers of equal length."); CollectionAssert.AreEqual(bytesExpected, bytesActual, "Files are not binary-equal."); } } + + public string Describe() + { + if (!string.IsNullOrEmpty(Label)) return Label; + return Filename; + } } } diff --git a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs index 6929ceb..c218ac0 100644 --- a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs +++ b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs @@ -33,8 +33,8 @@ private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize) { - // 1 test file per downloader. - var files = downloaders.Select(d => test.GenerateTestFile(testFileSize)).ToArray(); + // Generate 1 test file per downloader. + var files = downloaders.Select(d => GenerateTestFile(uploader, d, testFileSize)).ToArray(); // Upload all the test files to the uploader. var contentIds = files.Select(uploader.UploadFile).ToArray(); @@ -43,10 +43,18 @@ for (var i = 0; i < downloaders.Length; i++) { var expectedFile = files[i]; - var downloadedFile = downloaders[i].DownloadContent(contentIds[i]); + var downloadedFile = downloaders[i].DownloadContent(contentIds[i], $"{expectedFile.Label}DOWNLOADED"); expectedFile.AssertIsEqual(downloadedFile); } } + + private TestFile GenerateTestFile(IOnlineCodexNode uploader, IOnlineCodexNode downloader, ByteSize testFileSize) + { + var up = uploader.GetName().Replace("<", "").Replace(">", ""); + var down = downloader.GetName().Replace("<", "").Replace(">", ""); + var label = $"FROM{up}TO{down}"; + return test.GenerateTestFile(testFileSize, label); + } } } diff --git a/DistTestCore/OnlineCodexNode.cs b/DistTestCore/OnlineCodexNode.cs index 6e12c79..a1197f6 100644 --- a/DistTestCore/OnlineCodexNode.cs +++ b/DistTestCore/OnlineCodexNode.cs @@ -13,7 +13,7 @@ namespace DistTestCore CodexDebugPeerResponse GetDebugPeer(string peerId); CodexDebugPeerResponse GetDebugPeer(string peerId, TimeSpan timeout); ContentId UploadFile(TestFile file); - TestFile? DownloadContent(ContentId contentId); + TestFile? DownloadContent(ContentId contentId, string fileLabel = ""); void ConnectToPeer(IOnlineCodexNode node); ICodexNodeLog DownloadLog(); IMetricsAccess Metrics { get; } @@ -66,23 +66,24 @@ namespace DistTestCore public ContentId UploadFile(TestFile file) { - Log($"Uploading file of size {file.GetFileSize()}..."); + Log($"Uploading file '{file.Describe()}' of size {file.GetFileSize()}..."); using var fileStream = File.OpenRead(file.Filename); var response = CodexAccess.UploadFile(fileStream); if (response.StartsWith(UploadFailedMessage)) { Assert.Fail("Node failed to store block."); } + lifecycle.Log.AddStringReplace(response, $"(CID:{file.Describe()})"); Log($"Uploaded file. Received contentId: '{response}'."); return new ContentId(response); } - public TestFile? DownloadContent(ContentId contentId) + public TestFile? DownloadContent(ContentId contentId, string fileLabel = "") { Log($"Downloading for contentId: '{contentId.Id}'..."); - var file = lifecycle.FileManager.CreateEmptyTestFile(); + var file = lifecycle.FileManager.CreateEmptyTestFile(fileLabel); DownloadToFile(contentId.Id, file); - Log($"Downloaded file of size {file.GetFileSize()} to '{file.Filename}'."); + Log($"Downloaded file '{file.Describe()}' of size {file.GetFileSize()} to '{file.Filename}'."); return file; } diff --git a/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs b/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs new file mode 100644 index 0000000..b1e9bd6 --- /dev/null +++ b/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs @@ -0,0 +1,19 @@ +using DistTestCore; +using NUnit.Framework; + +namespace Tests.DownloadConnectivityTests +{ + [TestFixture] + public class FullyConnectedDownloadTests : AutoBootstrapDistTest + { + [TestCase(3)] + [TestCase(10)] + [TestCase(20)] + public void FullyConnectedDownloadTest(int numberOfNodes) + { + for (var i = 0; i < numberOfNodes; i++) SetupCodexNode(); + + PeerDownloadTestHelpers.AssertFullDownloadInterconnectivity(GetAllOnlineCodexNodes()); + } + } +} diff --git a/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs b/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs index 306d305..ad04144 100644 --- a/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs +++ b/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs @@ -56,7 +56,6 @@ namespace Tests.PeerDiscoveryTests private void AssertAllNodesConnected() { PeerConnectionTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes()); - //PeerDownloadTestHelpers.AssertFullDownloadInterconnectivity(GetAllOnlineCodexNodes()); } } } diff --git a/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs b/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs index a77cc3a..841b072 100644 --- a/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs +++ b/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs @@ -67,7 +67,6 @@ namespace Tests.PeerDiscoveryTests private void AssertAllNodesConnected() { PeerConnectionTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes()); - //PeerDownloadTestHelpers.AssertFullDownloadInterconnectivity(GetAllOnlineCodexNodes()); } } } From e33a6776e58dacc2402605f2593efd59c0646747 Mon Sep 17 00:00:00 2001 From: benbierens Date: Tue, 6 Jun 2023 14:36:37 +0200 Subject: [PATCH 2/9] Cleanup --- .../Helpers/PeerConnectionTestHelpers.cs | 12 +++++-- .../Helpers/PeerDownloadTestHelpers.cs | 20 +++++++++++- DistTestCore/OnlineCodexNode.cs | 4 ++- .../LayeredDiscoveryTests.cs | 8 ----- .../PeerDiscoveryTests/PeerDiscoveryTests.cs | 32 ------------------- 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/DistTestCore/Helpers/PeerConnectionTestHelpers.cs b/DistTestCore/Helpers/PeerConnectionTestHelpers.cs index 54f3c43..5eb0cdf 100644 --- a/DistTestCore/Helpers/PeerConnectionTestHelpers.cs +++ b/DistTestCore/Helpers/PeerConnectionTestHelpers.cs @@ -16,10 +16,18 @@ namespace DistTestCore.Helpers public void AssertFullyConnected(IEnumerable nodes) { - AssertFullyConnected(nodes.ToArray()); + var n = nodes.ToArray(); + + AssertFullyConnected(n); + + for (int i = 0; i < 5; i++) + { + Time.Sleep(TimeSpan.FromSeconds(30)); + AssertFullyConnected(n); + } } - public void AssertFullyConnected(params IOnlineCodexNode[] nodes) + private void AssertFullyConnected(IOnlineCodexNode[] nodes) { test.Log($"Asserting peers are fully-connected for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'..."); var entries = CreateEntries(nodes); diff --git a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs index c218ac0..1e8812c 100644 --- a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs +++ b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs @@ -1,4 +1,7 @@ -namespace DistTestCore.Helpers +using Nethereum.Model; +using NUnit.Framework; + +namespace DistTestCore.Helpers { public class PeerDownloadTestHelpers { @@ -17,6 +20,8 @@ public void AssertFullDownloadInterconnectivity(IEnumerable nodes, ByteSize testFileSize) { test.Log($"Asserting full download interconnectivity for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'..."); + var start = DateTime.UtcNow; + foreach (var node in nodes) { var uploader = node; @@ -29,6 +34,19 @@ } test.Log($"Success! Full download interconnectivity for nodes: {string.Join(",", nodes.Select(n => n.GetName()))}"); + var timeTaken = DateTime.UtcNow - start; + + AssertTimePerDownload(timeTaken, nodes.Count()); + } + + private void AssertTimePerDownload(TimeSpan timeTaken, int numberOfNodes) + { + var numberOfDownloads = numberOfNodes * (numberOfNodes - 1); + var timePerDownload = timeTaken / numberOfDownloads; + + test.Log($"Performed {numberOfDownloads} downloads in {timeTaken.TotalSeconds} seconds, for an average of {timePerDownload.TotalSeconds} seconds per download."); + + Assert.That(timePerDownload.TotalSeconds, Is.LessThan(20.0f), "Seconds-per-Download breached performance threshold."); } private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize) diff --git a/DistTestCore/OnlineCodexNode.cs b/DistTestCore/OnlineCodexNode.cs index a1197f6..270ebc1 100644 --- a/DistTestCore/OnlineCodexNode.cs +++ b/DistTestCore/OnlineCodexNode.cs @@ -73,7 +73,9 @@ namespace DistTestCore { Assert.Fail("Node failed to store block."); } - lifecycle.Log.AddStringReplace(response, $"(CID:{file.Describe()})"); + var logReplacement = $"(CID:{file.Describe()})"; + Log($"ContentId '{response}' is {logReplacement}"); + lifecycle.Log.AddStringReplace(response, logReplacement); Log($"Uploaded file. Received contentId: '{response}'."); return new ContentId(response); } diff --git a/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs b/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs index ad04144..aeb414a 100644 --- a/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs +++ b/Tests/PeerDiscoveryTests/LayeredDiscoveryTests.cs @@ -1,7 +1,6 @@ using DistTestCore; using DistTestCore.Helpers; using NUnit.Framework; -using Utils; namespace Tests.PeerDiscoveryTests { @@ -35,7 +34,6 @@ namespace Tests.PeerDiscoveryTests [TestCase(5)] [TestCase(10)] [TestCase(20)] - [TestCase(50)] public void NodeChainTest(int chainLength) { var node = SetupCodexNode(); @@ -45,12 +43,6 @@ namespace Tests.PeerDiscoveryTests } AssertAllNodesConnected(); - - for (int i = 0; i < 5; i++) - { - Time.Sleep(TimeSpan.FromSeconds(30)); - AssertAllNodesConnected(); - } } private void AssertAllNodesConnected() diff --git a/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs b/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs index 841b072..57b79cf 100644 --- a/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs +++ b/Tests/PeerDiscoveryTests/PeerDiscoveryTests.cs @@ -18,16 +18,6 @@ namespace Tests.PeerDiscoveryTests Assert.That(result.IsPeerFound, Is.False); } - [TestCase(2)] - [TestCase(3)] - [TestCase(10)] - public void VariableNodes(int number) - { - SetupCodexNodes(number); - - AssertAllNodesConnected(); - } - [TestCase(2)] [TestCase(3)] [TestCase(10)] @@ -42,28 +32,6 @@ namespace Tests.PeerDiscoveryTests AssertAllNodesConnected(); } - [TestCase(3, 3)] - [TestCase(3, 5)] - [TestCase(3, 10)] - [TestCase(5, 10)] - [TestCase(3, 20)] - [TestCase(5, 20)] - public void StagedVariableNodes(int numberOfNodes, int numberOfStages) - { - for (var i = 0; i < numberOfStages; i++) - { - SetupCodexNodes(numberOfNodes); - - AssertAllNodesConnected(); - } - - for (int i = 0; i < 5; i++) - { - Time.Sleep(TimeSpan.FromSeconds(30)); - AssertAllNodesConnected(); - } - } - private void AssertAllNodesConnected() { PeerConnectionTestHelpers.AssertFullyConnected(GetAllOnlineCodexNodes()); From 56dc1c632d3dd9688bbb609558465acdf24ed92b Mon Sep 17 00:00:00 2001 From: benbierens Date: Tue, 6 Jun 2023 16:10:30 +0200 Subject: [PATCH 3/9] Variable size download tests --- DistTestCore/ByteSize.cs | 9 ++++++++- DistTestCore/FileManager.cs | 2 +- .../Helpers/PeerDownloadTestHelpers.cs | 20 +++++++++---------- KubernetesWorkflow/K8sController.cs | 1 + LongTests/BasicTests/DownloadTests.cs | 19 ++++++++++++++++++ .../FullyConnectedDownloadTests.cs | 11 +++++----- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/DistTestCore/ByteSize.cs b/DistTestCore/ByteSize.cs index dc288bc..4760c83 100644 --- a/DistTestCore/ByteSize.cs +++ b/DistTestCore/ByteSize.cs @@ -2,8 +2,11 @@ { public class ByteSize { + private static readonly string[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; + public ByteSize(long sizeInBytes) { + if (sizeInBytes < 0) throw new ArgumentException("Cannot create ByteSize object with size less than 0. Was: " + sizeInBytes); SizeInBytes = sizeInBytes; } @@ -21,7 +24,11 @@ public override string ToString() { - return $"{SizeInBytes} bytes"; + if (SizeInBytes == 0) return "0" + sizeSuffixes[0]; + + var sizeOrder = Convert.ToInt32(Math.Floor(Math.Log(SizeInBytes, 1024))); + var digit = Math.Round(SizeInBytes / Math.Pow(1024, sizeOrder), 1); + return digit.ToString() + sizeSuffixes[sizeOrder]; } } diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index 62b5ba7..f2737fa 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -43,7 +43,7 @@ namespace DistTestCore { var result = CreateEmptyTestFile(label); GenerateFileBytes(result, size); - log.Log($"Generated {size.SizeInBytes} bytes of content for file '{result.Describe()}'."); + log.Log($"Generated {size} of content for file '{result.Describe()}'."); return result; } diff --git a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs index 1e8812c..0ce642b 100644 --- a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs +++ b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs @@ -1,5 +1,4 @@ -using Nethereum.Model; -using NUnit.Framework; +using NUnit.Framework; namespace DistTestCore.Helpers { @@ -12,11 +11,6 @@ namespace DistTestCore.Helpers this.test = test; } - public void AssertFullDownloadInterconnectivity(IEnumerable nodes) - { - AssertFullDownloadInterconnectivity(nodes, 1.MB()); - } - public void AssertFullDownloadInterconnectivity(IEnumerable nodes, ByteSize testFileSize) { test.Log($"Asserting full download interconnectivity for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'..."); @@ -36,17 +30,21 @@ namespace DistTestCore.Helpers test.Log($"Success! Full download interconnectivity for nodes: {string.Join(",", nodes.Select(n => n.GetName()))}"); var timeTaken = DateTime.UtcNow - start; - AssertTimePerDownload(timeTaken, nodes.Count()); + AssertTimePerDownload(timeTaken, nodes.Count(), testFileSize); } - private void AssertTimePerDownload(TimeSpan timeTaken, int numberOfNodes) + private void AssertTimePerDownload(TimeSpan timeTaken, int numberOfNodes, ByteSize size) { var numberOfDownloads = numberOfNodes * (numberOfNodes - 1); var timePerDownload = timeTaken / numberOfDownloads; + float sizeInMB = size.SizeInBytes / (1024.0f * 1024.0f); + var timePerMB = timePerDownload.TotalSeconds / sizeInMB; - test.Log($"Performed {numberOfDownloads} downloads in {timeTaken.TotalSeconds} seconds, for an average of {timePerDownload.TotalSeconds} seconds per download."); + test.Log($"Performed {numberOfDownloads} downloads of {size} in {timeTaken.TotalSeconds} seconds, for an average of {timePerMB} seconds per MB."); - Assert.That(timePerDownload.TotalSeconds, Is.LessThan(20.0f), "Seconds-per-Download breached performance threshold."); + var maxTimePerMB = 2.0f; + + Assert.That(timePerMB, Is.LessThan(maxTimePerMB), "Seconds-per-MB performance threshold breached."); } private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize) diff --git a/KubernetesWorkflow/K8sController.cs b/KubernetesWorkflow/K8sController.cs index e0f8627..6174291 100644 --- a/KubernetesWorkflow/K8sController.cs +++ b/KubernetesWorkflow/K8sController.cs @@ -391,6 +391,7 @@ namespace KubernetesWorkflow { Name = recipe.Name, Image = recipe.Image, + ImagePullPolicy = "Always", Ports = CreateContainerPorts(recipe), Env = CreateEnv(recipe) }; diff --git a/LongTests/BasicTests/DownloadTests.cs b/LongTests/BasicTests/DownloadTests.cs index 5034462..828cdaa 100644 --- a/LongTests/BasicTests/DownloadTests.cs +++ b/LongTests/BasicTests/DownloadTests.cs @@ -6,6 +6,25 @@ namespace TestsLong.BasicTests [TestFixture] public class DownloadTests : DistTest { + [Test] + [Combinatorial] + [UseLongTimeouts] + public void DownloadCorrectnessTest( + [Values(1, 10, 100, 1024)] int sizeInMB, + [Values(1, 10, 100, 1024)] int multiplier) + { + var size = (sizeInMB * multiplier).MB(); + + var expectedFile = GenerateTestFile(size); + + var node = SetupCodexNode(); + var cid = node.UploadFile(expectedFile); + var actualFile = node.DownloadContent(cid); + + expectedFile.AssertIsEqual(actualFile); + } + + [TestCase(3, 500)] [TestCase(5, 100)] [TestCase(10, 256)] diff --git a/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs b/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs index b1e9bd6..ff3f62e 100644 --- a/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs +++ b/Tests/DownloadConnectivityTests/FullyConnectedDownloadTests.cs @@ -6,14 +6,15 @@ namespace Tests.DownloadConnectivityTests [TestFixture] public class FullyConnectedDownloadTests : AutoBootstrapDistTest { - [TestCase(3)] - [TestCase(10)] - [TestCase(20)] - public void FullyConnectedDownloadTest(int numberOfNodes) + [Test] + [Combinatorial] + public void FullyConnectedDownloadTest( + [Values(3, 10, 20)] int numberOfNodes, + [Values(1, 10, 100)] int sizeMBs) { for (var i = 0; i < numberOfNodes; i++) SetupCodexNode(); - PeerDownloadTestHelpers.AssertFullDownloadInterconnectivity(GetAllOnlineCodexNodes()); + PeerDownloadTestHelpers.AssertFullDownloadInterconnectivity(GetAllOnlineCodexNodes(), sizeMBs.MB()); } } } From d2d7f3dea5253e3e17a33e4d40ad6043f108cf6c Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 7 Jun 2023 08:30:10 +0200 Subject: [PATCH 4/9] Logging upload/download times and adds performance threshold assertions to large-file tests. --- DistTestCore/ByteSize.cs | 5 +++ DistTestCore/Codex/CodexContainerRecipe.cs | 4 ++ DistTestCore/DistTest.cs | 1 - .../Helpers/PeerDownloadTestHelpers.cs | 15 ++++--- DistTestCore/OnlineCodexNode.cs | 14 +++++-- Logging/Stopwatch.cs | 8 ++++ LongTests/BasicTests/DownloadTests.cs | 19 --------- LongTests/BasicTests/LargeFileTests.cs | 39 +++++++++++++++---- LongTests/Parallelism.cs | 6 +++ 9 files changed, 71 insertions(+), 40 deletions(-) create mode 100644 LongTests/Parallelism.cs diff --git a/DistTestCore/ByteSize.cs b/DistTestCore/ByteSize.cs index 4760c83..28ec49c 100644 --- a/DistTestCore/ByteSize.cs +++ b/DistTestCore/ByteSize.cs @@ -12,6 +12,11 @@ public long SizeInBytes { get; } + public long ToMB() + { + return SizeInBytes / (1024 * 1024); + } + public override bool Equals(object? obj) { return obj is ByteSize size && SizeInBytes == size.SizeInBytes; diff --git a/DistTestCore/Codex/CodexContainerRecipe.cs b/DistTestCore/Codex/CodexContainerRecipe.cs index 5b25a2f..f327927 100644 --- a/DistTestCore/Codex/CodexContainerRecipe.cs +++ b/DistTestCore/Codex/CodexContainerRecipe.cs @@ -14,6 +14,10 @@ namespace DistTestCore.Codex public const string MetricsPortTag = "metrics_port"; public const string DiscoveryPortTag = "discovery-port"; + // Used by tests for time-constraint assersions. + public static readonly TimeSpan MaxUploadTimePerMegabyte = TimeSpan.FromSeconds(2.0); + public static readonly TimeSpan MaxDownloadTimePerMegabyte = TimeSpan.FromSeconds(2.0); + protected override string Image => DockerImage; protected override void Initialize(StartupConfig startupConfig) diff --git a/DistTestCore/DistTest.cs b/DistTestCore/DistTest.cs index df345e8..a93c180 100644 --- a/DistTestCore/DistTest.cs +++ b/DistTestCore/DistTest.cs @@ -10,7 +10,6 @@ using System.Reflection; namespace DistTestCore { - [SetUpFixture] [Parallelizable(ParallelScope.All)] public abstract class DistTest { diff --git a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs index 0ce642b..a39e945 100644 --- a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs +++ b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using DistTestCore.Codex; +using NUnit.Framework; namespace DistTestCore.Helpers { @@ -30,21 +31,19 @@ namespace DistTestCore.Helpers test.Log($"Success! Full download interconnectivity for nodes: {string.Join(",", nodes.Select(n => n.GetName()))}"); var timeTaken = DateTime.UtcNow - start; - AssertTimePerDownload(timeTaken, nodes.Count(), testFileSize); + AssertTimePerMB(timeTaken, nodes.Count(), testFileSize); } - private void AssertTimePerDownload(TimeSpan timeTaken, int numberOfNodes, ByteSize size) + private void AssertTimePerMB(TimeSpan timeTaken, int numberOfNodes, ByteSize size) { var numberOfDownloads = numberOfNodes * (numberOfNodes - 1); var timePerDownload = timeTaken / numberOfDownloads; - float sizeInMB = size.SizeInBytes / (1024.0f * 1024.0f); - var timePerMB = timePerDownload.TotalSeconds / sizeInMB; + float sizeInMB = size.ToMB(); + var timePerMB = timePerDownload / sizeInMB; test.Log($"Performed {numberOfDownloads} downloads of {size} in {timeTaken.TotalSeconds} seconds, for an average of {timePerMB} seconds per MB."); - var maxTimePerMB = 2.0f; - - Assert.That(timePerMB, Is.LessThan(maxTimePerMB), "Seconds-per-MB performance threshold breached."); + Assert.That(timePerMB, Is.LessThan(CodexContainerRecipe.MaxDownloadTimePerMegabyte), "MaxDownloadTimePerMegabyte performance threshold breached."); } private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize) diff --git a/DistTestCore/OnlineCodexNode.cs b/DistTestCore/OnlineCodexNode.cs index 270ebc1..46ca044 100644 --- a/DistTestCore/OnlineCodexNode.cs +++ b/DistTestCore/OnlineCodexNode.cs @@ -2,6 +2,7 @@ using DistTestCore.Logs; using DistTestCore.Marketplace; using DistTestCore.Metrics; +using Logging; using NUnit.Framework; namespace DistTestCore @@ -66,9 +67,14 @@ namespace DistTestCore public ContentId UploadFile(TestFile file) { - Log($"Uploading file '{file.Describe()}' of size {file.GetFileSize()}..."); using var fileStream = File.OpenRead(file.Filename); - var response = CodexAccess.UploadFile(fileStream); + + var logMessage = $"Uploading file '{file.Describe()}' of size {file.GetFileSize()}..."; + var response = Stopwatch.Measure(lifecycle.Log, logMessage, () => + { + return CodexAccess.UploadFile(fileStream); + }); + if (response.StartsWith(UploadFailedMessage)) { Assert.Fail("Node failed to store block."); @@ -82,9 +88,9 @@ namespace DistTestCore public TestFile? DownloadContent(ContentId contentId, string fileLabel = "") { - Log($"Downloading for contentId: '{contentId.Id}'..."); + var logMessage = $"Downloading for contentId: '{contentId.Id}'..."; var file = lifecycle.FileManager.CreateEmptyTestFile(fileLabel); - DownloadToFile(contentId.Id, file); + Stopwatch.Measure(lifecycle.Log, logMessage, () => DownloadToFile(contentId.Id, file)); Log($"Downloaded file '{file.Describe()}' of size {file.GetFileSize()} to '{file.Filename}'."); return file; } diff --git a/Logging/Stopwatch.cs b/Logging/Stopwatch.cs index 9f8a346..f62f7f6 100644 --- a/Logging/Stopwatch.cs +++ b/Logging/Stopwatch.cs @@ -23,6 +23,14 @@ namespace Logging sw.End(); } + public static T Measure(BaseLog log, string name, Func action, bool debug = false) + { + var sw = Begin(log, name, debug); + var result = action(); + sw.End(); + return result; + } + public static Stopwatch Begin(BaseLog log) { return Begin(log, ""); diff --git a/LongTests/BasicTests/DownloadTests.cs b/LongTests/BasicTests/DownloadTests.cs index 828cdaa..5034462 100644 --- a/LongTests/BasicTests/DownloadTests.cs +++ b/LongTests/BasicTests/DownloadTests.cs @@ -6,25 +6,6 @@ namespace TestsLong.BasicTests [TestFixture] public class DownloadTests : DistTest { - [Test] - [Combinatorial] - [UseLongTimeouts] - public void DownloadCorrectnessTest( - [Values(1, 10, 100, 1024)] int sizeInMB, - [Values(1, 10, 100, 1024)] int multiplier) - { - var size = (sizeInMB * multiplier).MB(); - - var expectedFile = GenerateTestFile(size); - - var node = SetupCodexNode(); - var cid = node.UploadFile(expectedFile); - var actualFile = node.DownloadContent(cid); - - expectedFile.AssertIsEqual(actualFile); - } - - [TestCase(3, 500)] [TestCase(5, 100)] [TestCase(10, 256)] diff --git a/LongTests/BasicTests/LargeFileTests.cs b/LongTests/BasicTests/LargeFileTests.cs index 3149ee3..636ff79 100644 --- a/LongTests/BasicTests/LargeFileTests.cs +++ b/LongTests/BasicTests/LargeFileTests.cs @@ -1,4 +1,5 @@ using DistTestCore; +using DistTestCore.Codex; using NUnit.Framework; namespace TestsLong.BasicTests @@ -6,19 +7,41 @@ namespace TestsLong.BasicTests [TestFixture] public class LargeFileTests : DistTest { - [Test, UseLongTimeouts] - public void OneClientLargeFileTest() + [Test] + [Combinatorial] + [UseLongTimeouts] + public void DownloadCorrectnessTest( + [Values(1, 10, 100, 1024)] int sizeInMB, + [Values(1, 10, 100, 1024)] int multiplier) { - var primary = SetupCodexNode(s => s - .WithStorageQuota(20.GB())); + var size = (sizeInMB * multiplier).MB(); - var testFile = GenerateTestFile(10.GB()); + var expectedFile = GenerateTestFile(size); - var contentId = primary.UploadFile(testFile); + var node = SetupCodexNode(); - var downloadedFile = primary.DownloadContent(contentId); + var uploadStart = DateTime.UtcNow; + var cid = node.UploadFile(expectedFile); + var downloadStart = DateTime.UtcNow; + var actualFile = node.DownloadContent(cid); + var downloadFinished = DateTime.UtcNow; + + expectedFile.AssertIsEqual(actualFile); + AssertTimeConstraint(uploadStart, downloadStart, downloadFinished, size); + } + + private void AssertTimeConstraint(DateTime uploadStart, DateTime downloadStart, DateTime downloadFinished, ByteSize size) + { + float sizeInMB = size.ToMB(); + var uploadTimePerMB = (uploadStart - downloadStart) / sizeInMB; + var downloadTimePerMB = (downloadStart - downloadFinished) / sizeInMB; + + Assert.That(uploadTimePerMB, Is.LessThan(CodexContainerRecipe.MaxUploadTimePerMegabyte), + "MaxUploadTimePerMegabyte performance threshold breached."); + + Assert.That(downloadTimePerMB, Is.LessThan(CodexContainerRecipe.MaxDownloadTimePerMegabyte), + "MaxDownloadTimePerMegabyte performance threshold breached."); - testFile.AssertIsEqual(downloadedFile); } } } diff --git a/LongTests/Parallelism.cs b/LongTests/Parallelism.cs new file mode 100644 index 0000000..f45d8f2 --- /dev/null +++ b/LongTests/Parallelism.cs @@ -0,0 +1,6 @@ +using NUnit.Framework; + +[assembly: LevelOfParallelism(1)] +namespace Tests +{ +} From 7ae03938c379c45f5c78ee405a3d28cd3c89d641 Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 7 Jun 2023 09:32:56 +0200 Subject: [PATCH 5/9] Fixes storage quota for large file tests. --- DistTestCore/ByteSize.cs | 11 ++++------- DistTestCore/FileManager.cs | 16 ++++++++-------- DistTestCore/OnlineCodexNode.cs | 4 ++-- LongTests/BasicTests/LargeFileTests.cs | 12 ++++++------ LongTests/BasicTests/TestInfraTests.cs | 21 --------------------- Utils/Formatter.cs | 16 ++++++++++++++++ 6 files changed, 36 insertions(+), 44 deletions(-) create mode 100644 Utils/Formatter.cs diff --git a/DistTestCore/ByteSize.cs b/DistTestCore/ByteSize.cs index 28ec49c..8d47cf2 100644 --- a/DistTestCore/ByteSize.cs +++ b/DistTestCore/ByteSize.cs @@ -1,8 +1,9 @@ -namespace DistTestCore +using Utils; + +namespace DistTestCore { public class ByteSize { - private static readonly string[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; public ByteSize(long sizeInBytes) { @@ -29,11 +30,7 @@ public override string ToString() { - if (SizeInBytes == 0) return "0" + sizeSuffixes[0]; - - var sizeOrder = Convert.ToInt32(Math.Floor(Math.Log(SizeInBytes, 1024))); - var digit = Math.Round(SizeInBytes / Math.Pow(1024, sizeOrder), 1); - return digit.ToString() + sizeSuffixes[sizeOrder]; + return Formatter.FormatByteSize(SizeInBytes); } } diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index f2737fa..b9f2264 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -43,7 +43,7 @@ namespace DistTestCore { var result = CreateEmptyTestFile(label); GenerateFileBytes(result, size); - log.Log($"Generated {size} of content for file '{result.Describe()}'."); + log.Log($"Generated file '{result.Describe()}'."); return result; } @@ -117,12 +117,6 @@ namespace DistTestCore public string Filename { get; } public string Label { get; } - public long GetFileSize() - { - var info = new FileInfo(Filename); - return info.Length; - } - public void AssertIsEqual(TestFile? actual) { if (actual == null) Assert.Fail("TestFile is null."); @@ -157,7 +151,13 @@ namespace DistTestCore public string Describe() { if (!string.IsNullOrEmpty(Label)) return Label; - return Filename; + return $"'{Filename}' ({Formatter.FormatByteSize(GetFileSize())})"; + } + + private long GetFileSize() + { + var info = new FileInfo(Filename); + return info.Length; } } } diff --git a/DistTestCore/OnlineCodexNode.cs b/DistTestCore/OnlineCodexNode.cs index 46ca044..d53f2c2 100644 --- a/DistTestCore/OnlineCodexNode.cs +++ b/DistTestCore/OnlineCodexNode.cs @@ -69,7 +69,7 @@ namespace DistTestCore { using var fileStream = File.OpenRead(file.Filename); - var logMessage = $"Uploading file '{file.Describe()}' of size {file.GetFileSize()}..."; + var logMessage = $"Uploading file {file.Describe()}..."; var response = Stopwatch.Measure(lifecycle.Log, logMessage, () => { return CodexAccess.UploadFile(fileStream); @@ -91,7 +91,7 @@ namespace DistTestCore var logMessage = $"Downloading for contentId: '{contentId.Id}'..."; var file = lifecycle.FileManager.CreateEmptyTestFile(fileLabel); Stopwatch.Measure(lifecycle.Log, logMessage, () => DownloadToFile(contentId.Id, file)); - Log($"Downloaded file '{file.Describe()}' of size {file.GetFileSize()} to '{file.Filename}'."); + Log($"Downloaded file {file.Describe()} to '{file.Filename}'."); return file; } diff --git a/LongTests/BasicTests/LargeFileTests.cs b/LongTests/BasicTests/LargeFileTests.cs index 636ff79..a96184d 100644 --- a/LongTests/BasicTests/LargeFileTests.cs +++ b/LongTests/BasicTests/LargeFileTests.cs @@ -14,11 +14,12 @@ namespace TestsLong.BasicTests [Values(1, 10, 100, 1024)] int sizeInMB, [Values(1, 10, 100, 1024)] int multiplier) { - var size = (sizeInMB * multiplier).MB(); + long size = (sizeInMB * multiplier); + var sizeMB = size.MB(); - var expectedFile = GenerateTestFile(size); + var expectedFile = GenerateTestFile(sizeMB); - var node = SetupCodexNode(); + var node = SetupCodexNode(s => s.WithStorageQuota((size + 10).MB())); var uploadStart = DateTime.UtcNow; var cid = node.UploadFile(expectedFile); @@ -30,9 +31,9 @@ namespace TestsLong.BasicTests AssertTimeConstraint(uploadStart, downloadStart, downloadFinished, size); } - private void AssertTimeConstraint(DateTime uploadStart, DateTime downloadStart, DateTime downloadFinished, ByteSize size) + private void AssertTimeConstraint(DateTime uploadStart, DateTime downloadStart, DateTime downloadFinished, long size) { - float sizeInMB = size.ToMB(); + float sizeInMB = size; var uploadTimePerMB = (uploadStart - downloadStart) / sizeInMB; var downloadTimePerMB = (downloadStart - downloadFinished) / sizeInMB; @@ -41,7 +42,6 @@ namespace TestsLong.BasicTests Assert.That(downloadTimePerMB, Is.LessThan(CodexContainerRecipe.MaxDownloadTimePerMegabyte), "MaxDownloadTimePerMegabyte performance threshold breached."); - } } } diff --git a/LongTests/BasicTests/TestInfraTests.cs b/LongTests/BasicTests/TestInfraTests.cs index 9b3111f..a6f68e3 100644 --- a/LongTests/BasicTests/TestInfraTests.cs +++ b/LongTests/BasicTests/TestInfraTests.cs @@ -26,26 +26,5 @@ namespace TestsLong.BasicTests Assert.That(!string.IsNullOrEmpty(n.GetDebugInfo().id)); } } - - [Test, UseLongTimeouts] - public void DownloadConsistencyTest() - { - var primary = SetupCodexNode(s => s - .WithStorageQuota(2.MB())); - - var testFile = GenerateTestFile(1.MB()); - - var contentId = primary.UploadFile(testFile); - - var files = new List(); - for (var i = 0; i < 100; i++) - { - files.Add(primary.DownloadContent(contentId)); - } - - Assert.That(files.All(f => f != null)); - Assert.That(files.All(f => f!.GetFileSize() == testFile.GetFileSize())); - foreach (var file in files) file!.AssertIsEqual(testFile); - } } } diff --git a/Utils/Formatter.cs b/Utils/Formatter.cs new file mode 100644 index 0000000..1ea1550 --- /dev/null +++ b/Utils/Formatter.cs @@ -0,0 +1,16 @@ +namespace Utils +{ + public static class Formatter + { + private static readonly string[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; + + public static string FormatByteSize(long bytes) + { + if (bytes == 0) return "0" + sizeSuffixes[0]; + + var sizeOrder = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); + var digit = Math.Round(bytes / Math.Pow(1024, sizeOrder), 1); + return digit.ToString() + sizeSuffixes[sizeOrder]; + } + } +} From 677ead4fd3a55bcad42af83fef522484a707ff4e Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 7 Jun 2023 09:59:00 +0200 Subject: [PATCH 6/9] Faster test file generation. --- DistTestCore/FileManager.cs | 50 ++++++++++++++++++++++---- LongTests/BasicTests/LargeFileTests.cs | 41 +++++++++++++++++---- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index b9f2264..d4d893b 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -15,7 +15,7 @@ namespace DistTestCore public class FileManager : IFileManager { - public const int ChunkSize = 1024 * 1024; + public const int ChunkSize = 1024 * 1024 * 100; private static NumberSource folderNumberSource = new NumberSource(0); private readonly Random random = new Random(); private readonly TestLog log; @@ -41,9 +41,9 @@ namespace DistTestCore public TestFile GenerateTestFile(ByteSize size, string label) { - var result = CreateEmptyTestFile(label); - GenerateFileBytes(result, size); - log.Log($"Generated file '{result.Describe()}'."); + var sw = Stopwatch.Begin(log); + var result = GenerateFile(size, label); + sw.End($"Generated file '{result.Describe()}'."); return result; } @@ -73,14 +73,50 @@ namespace DistTestCore } } + private TestFile GenerateFile(ByteSize size, string label) + { + var result = CreateEmptyTestFile(label); + CheckSpaceAvailable(result, size); + + GenerateFileBytes(result, size); + return result; + } + + private void CheckSpaceAvailable(TestFile testFile, ByteSize size) + { + var file = new FileInfo(testFile.Filename); + var drive = new DriveInfo(file.Directory!.Root.FullName); + + var spaceAvailable = drive.TotalFreeSpace; + + if (spaceAvailable < size.SizeInBytes) + { + var msg = $"Inconclusive: Not enough disk space to perform test. " + + $"{Formatter.FormatByteSize(size.SizeInBytes)} required. " + + $"{Formatter.FormatByteSize(spaceAvailable)} available."; + + log.Log(msg); + Assert.Inconclusive(msg); + } + } + private void GenerateFileBytes(TestFile result, ByteSize size) { long bytesLeft = size.SizeInBytes; + int chunkSize = ChunkSize; while (bytesLeft > 0) { - var length = Math.Min(bytesLeft, ChunkSize); - AppendRandomBytesToFile(result, length); - bytesLeft -= length; + try + { + var length = Math.Min(bytesLeft, chunkSize); + AppendRandomBytesToFile(result, length); + bytesLeft -= length; + } + catch + { + chunkSize = chunkSize / 2; + if (chunkSize < 1024) throw; + } } } diff --git a/LongTests/BasicTests/LargeFileTests.cs b/LongTests/BasicTests/LargeFileTests.cs index a96184d..9eb3a89 100644 --- a/LongTests/BasicTests/LargeFileTests.cs +++ b/LongTests/BasicTests/LargeFileTests.cs @@ -1,20 +1,47 @@ using DistTestCore; using DistTestCore.Codex; using NUnit.Framework; +using NUnit.Framework.Interfaces; namespace TestsLong.BasicTests { [TestFixture] public class LargeFileTests : DistTest { - [Test] - [Combinatorial] - [UseLongTimeouts] - public void DownloadCorrectnessTest( - [Values(1, 10, 100, 1024)] int sizeInMB, - [Values(1, 10, 100, 1024)] int multiplier) + #region Abort test run after first failure + + private bool stop; + + [SetUp] + public void SetUp() + { + if (stop) + { + Assert.Inconclusive("Previous test failed"); + } + } + + [TearDown] + public void TearDown() + { + if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed) + { + stop = true; + } + } + + #endregion + + [TestCase( 1 * 1)] // 1 MB + [TestCase( 1 * 10)] + [TestCase( 1 * 100)] + [TestCase( 1 * 1024)] // 1 GB + [TestCase( 1024 * 10)] + [TestCase( 1024 * 100)] + [TestCase( 1024 * 1024)] // 1 TB :O + [UseLongTimeouts] + public void DownloadCorrectnessTest(long size) { - long size = (sizeInMB * multiplier); var sizeMB = size.MB(); var expectedFile = GenerateTestFile(sizeMB); From b4f144a7fbfbcb551eacad38115111b629370116 Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 7 Jun 2023 10:56:25 +0200 Subject: [PATCH 7/9] Speeds up file-equal assertions hugely --- DistTestCore/FileManager.cs | 40 ++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index d4d893b..69e0ef3 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -1,5 +1,6 @@ using Logging; using NUnit.Framework; +using System.Runtime.InteropServices; using Utils; namespace DistTestCore @@ -154,11 +155,33 @@ namespace DistTestCore public string Label { get; } public void AssertIsEqual(TestFile? actual) + { + var sw = Stopwatch.Begin(log); + try + { + AssertEqual(actual); + } + finally + { + sw.End($"{nameof(TestFile)}.{nameof(AssertIsEqual)}"); + } + } + + public string Describe() + { + if (!string.IsNullOrEmpty(Label)) return Label; + return $"'{Filename}' ({Formatter.FormatByteSize(GetFileSize())})"; + } + + private void AssertEqual(TestFile? actual) { if (actual == null) Assert.Fail("TestFile is null."); if (actual == this || actual!.Filename == Filename) Assert.Fail("TestFile is compared to itself."); - Assert.That(actual.GetFileSize(), Is.EqualTo(GetFileSize()), "Files are not of equal length."); + Stopwatch.Measure(log, "sizes", () => + { + Assert.That(actual.GetFileSize(), Is.EqualTo(GetFileSize()), "Files are not of equal length."); + }); using var streamExpected = new FileStream(Filename, FileMode.Open, FileAccess.Read); using var streamActual = new FileStream(actual.Filename, FileMode.Open, FileAccess.Read); @@ -179,15 +202,14 @@ namespace DistTestCore log.Log($"OK: '{Describe()}' is equal to '{actual.Describe()}'."); return; } - Assert.That(readActual, Is.EqualTo(readExpected), "Unable to read buffers of equal length."); - CollectionAssert.AreEqual(bytesExpected, bytesActual, "Files are not binary-equal."); - } - } - public string Describe() - { - if (!string.IsNullOrEmpty(Label)) return Label; - return $"'{Filename}' ({Formatter.FormatByteSize(GetFileSize())})"; + Assert.That(readActual, Is.EqualTo(readExpected), "Unable to read buffers of equal length."); + + for (var i = 0; i < readActual; i++) + { + if (bytesExpected[i] != bytesActual[i]) Assert.Fail("File contents not equal."); + } + } } private long GetFileSize() From 519069f97ffb2615ed66e996df0052d6c4d6112b Mon Sep 17 00:00:00 2001 From: benbierens Date: Thu, 8 Jun 2023 13:23:26 +0200 Subject: [PATCH 8/9] Cleanup --- DistTestCore/FileManager.cs | 10 ++++------ DistTestCore/Marketplace/MarketplaceAccessFactory.cs | 1 - DistTestCore/Timing.cs | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/DistTestCore/FileManager.cs b/DistTestCore/FileManager.cs index 69e0ef3..5ebae09 100644 --- a/DistTestCore/FileManager.cs +++ b/DistTestCore/FileManager.cs @@ -169,8 +169,9 @@ namespace DistTestCore public string Describe() { - if (!string.IsNullOrEmpty(Label)) return Label; - return $"'{Filename}' ({Formatter.FormatByteSize(GetFileSize())})"; + var sizePostfix = $" ({Formatter.FormatByteSize(GetFileSize())})"; + if (!string.IsNullOrEmpty(Label)) return Label + sizePostfix; + return $"'{Filename}'{sizePostfix}"; } private void AssertEqual(TestFile? actual) @@ -178,10 +179,7 @@ namespace DistTestCore if (actual == null) Assert.Fail("TestFile is null."); if (actual == this || actual!.Filename == Filename) Assert.Fail("TestFile is compared to itself."); - Stopwatch.Measure(log, "sizes", () => - { - Assert.That(actual.GetFileSize(), Is.EqualTo(GetFileSize()), "Files are not of equal length."); - }); + Assert.That(actual.GetFileSize(), Is.EqualTo(GetFileSize()), "Files are not of equal length."); using var streamExpected = new FileStream(Filename, FileMode.Open, FileAccess.Read); using var streamActual = new FileStream(actual.Filename, FileMode.Open, FileAccess.Read); diff --git a/DistTestCore/Marketplace/MarketplaceAccessFactory.cs b/DistTestCore/Marketplace/MarketplaceAccessFactory.cs index 5ad52eb..ac59556 100644 --- a/DistTestCore/Marketplace/MarketplaceAccessFactory.cs +++ b/DistTestCore/Marketplace/MarketplaceAccessFactory.cs @@ -1,5 +1,4 @@ using DistTestCore.Codex; -using Logging; namespace DistTestCore.Marketplace { diff --git a/DistTestCore/Timing.cs b/DistTestCore/Timing.cs index cff8b09..c395d07 100644 --- a/DistTestCore/Timing.cs +++ b/DistTestCore/Timing.cs @@ -31,7 +31,7 @@ namespace DistTestCore public TimeSpan HttpCallRetryDelay() { - return TimeSpan.FromSeconds(3); + return TimeSpan.FromSeconds(1); } public TimeSpan WaitForK8sServiceDelay() @@ -64,7 +64,7 @@ namespace DistTestCore public TimeSpan HttpCallRetryDelay() { - return TimeSpan.FromMinutes(5); + return TimeSpan.FromSeconds(2); } public TimeSpan WaitForK8sServiceDelay() From 9b03fff032372a29ecf9f9b8f50102fd4acb2ee2 Mon Sep 17 00:00:00 2001 From: benbierens Date: Tue, 20 Jun 2023 13:37:58 +0200 Subject: [PATCH 9/9] Time formatting in peer download test helper --- DistTestCore/Helpers/PeerDownloadTestHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs index a39e945..2626d5f 100644 --- a/DistTestCore/Helpers/PeerDownloadTestHelpers.cs +++ b/DistTestCore/Helpers/PeerDownloadTestHelpers.cs @@ -41,7 +41,7 @@ namespace DistTestCore.Helpers float sizeInMB = size.ToMB(); var timePerMB = timePerDownload / sizeInMB; - test.Log($"Performed {numberOfDownloads} downloads of {size} in {timeTaken.TotalSeconds} seconds, for an average of {timePerMB} seconds per MB."); + test.Log($"Performed {numberOfDownloads} downloads of {size} in {timeTaken.TotalSeconds} seconds, for an average of {timePerMB.TotalSeconds} seconds per MB."); Assert.That(timePerMB, Is.LessThan(CodexContainerRecipe.MaxDownloadTimePerMegabyte), "MaxDownloadTimePerMegabyte performance threshold breached."); }