From 09554da362f72fd2c474fc24513997d0ba0241d9 Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 6 Dec 2023 10:50:02 +0100 Subject: [PATCH] Adds transfer speeds to status logs. --- Framework/Utils/ByteSize.cs | 5 +++ ProjectPlugins/CodexPlugin/TransferSpeeds.cs | 31 ++++++++++++++----- Tests/CodexContinuousTests/SingleTestRun.cs | 5 +++ Tests/CodexTests/CodexDistTest.cs | 32 ++++++++++++++------ Tests/DistTestCore/DistTest.cs | 18 ++++++++++- 5 files changed, 72 insertions(+), 19 deletions(-) diff --git a/Framework/Utils/ByteSize.cs b/Framework/Utils/ByteSize.cs index 69d5f91e..a5204c71 100644 --- a/Framework/Utils/ByteSize.cs +++ b/Framework/Utils/ByteSize.cs @@ -51,6 +51,11 @@ public BytesPerSecond(long sizeInBytes) : base(sizeInBytes) { } + + public override string ToString() + { + return base.ToString() + "/s"; + } } public static class ByteSizeIntExtensions diff --git a/ProjectPlugins/CodexPlugin/TransferSpeeds.cs b/ProjectPlugins/CodexPlugin/TransferSpeeds.cs index ae1f2917..b745f644 100644 --- a/ProjectPlugins/CodexPlugin/TransferSpeeds.cs +++ b/ProjectPlugins/CodexPlugin/TransferSpeeds.cs @@ -4,8 +4,8 @@ namespace CodexPlugin { public interface ITransferSpeeds { - BytesPerSecond GetUploadSpeed(); - BytesPerSecond GetDownloadSpeed(); + BytesPerSecond? GetUploadSpeed(); + BytesPerSecond? GetDownloadSpeed(); } public class TransferSpeeds : ITransferSpeeds @@ -23,14 +23,16 @@ namespace CodexPlugin downloads.Add(Convert(bytes, duration)); } - public BytesPerSecond GetUploadSpeed() + public BytesPerSecond? GetUploadSpeed() { - return Average(uploads); + if (!uploads.Any()) return null; + return uploads.Average(); } - public BytesPerSecond GetDownloadSpeed() + public BytesPerSecond? GetDownloadSpeed() { - return Average(downloads); + if (!downloads.Any()) return null; + return downloads.Average(); } private static BytesPerSecond Convert(ByteSize size, TimeSpan duration) @@ -40,13 +42,26 @@ namespace CodexPlugin return new BytesPerSecond(System.Convert.ToInt64(Math.Round(bytes / seconds))); } + } - private static BytesPerSecond Average(List list) + public static class ListExtensions + { + public static BytesPerSecond Average(this List list) { double sum = list.Sum(i => i.SizeInBytes); double num = list.Count; - return new BytesPerSecond(System.Convert.ToInt64(Math.Round(sum / num))); + return new BytesPerSecond(Convert.ToInt64(Math.Round(sum / num))); + } + + public static BytesPerSecond? OptionalAverage(this List? list) + { + if (list == null || !list.Any() || !list.Any(i => i != null)) return null; + var values = list.Where(i => i != null).Cast().ToArray(); + double sum = values.Sum(i => i.SizeInBytes); + double num = values.Length; + + return new BytesPerSecond(Convert.ToInt64(Math.Round(sum / num))); } } } diff --git a/Tests/CodexContinuousTests/SingleTestRun.cs b/Tests/CodexContinuousTests/SingleTestRun.cs index 2ab5a338..39b45e51 100644 --- a/Tests/CodexContinuousTests/SingleTestRun.cs +++ b/Tests/CodexContinuousTests/SingleTestRun.cs @@ -197,6 +197,11 @@ namespace ContinuousTests if (error.Contains(":")) error = error.Substring(1 + error.LastIndexOf(":")); result.Add("error", error); + var upload = nodes.Select(n => n.TransferSpeeds.GetUploadSpeed()).ToList()!.OptionalAverage(); + var download = nodes.Select(n => n.TransferSpeeds.GetDownloadSpeed()).ToList()!.OptionalAverage(); + if (upload != null) result.Add("avgupload", upload.ToString()); + if (download != null) result.Add("avgdownload", download.ToString()); + return result; } diff --git a/Tests/CodexTests/CodexDistTest.cs b/Tests/CodexTests/CodexDistTest.cs index 4d6dab23..a8b406ce 100644 --- a/Tests/CodexTests/CodexDistTest.cs +++ b/Tests/CodexTests/CodexDistTest.cs @@ -6,14 +6,13 @@ using Core; using DistTestCore; using DistTestCore.Helpers; using DistTestCore.Logs; -using NUnit.Framework; using NUnit.Framework.Constraints; namespace CodexTests { public class CodexDistTest : DistTest { - private readonly List onlineCodexNodes = new List(); + private readonly Dictionary> onlineCodexNodes = new Dictionary>(); public CodexDistTest() { @@ -23,12 +22,6 @@ namespace CodexTests ProjectPlugin.Load(); } - [TearDown] - public void TearDownCodexFixture() - { - onlineCodexNodes.Clear(); - } - protected override void Initialize(FixtureLog fixtureLog) { var localBuilder = new LocalCodexBuilder(fixtureLog); @@ -36,6 +29,16 @@ namespace CodexTests localBuilder.Build(); } + protected override void LifecycleStart(TestLifecycle lifecycle) + { + onlineCodexNodes.Add(lifecycle, new List()); + } + + protected override void LifecycleStop(TestLifecycle lifecycle) + { + onlineCodexNodes.Remove(lifecycle); + } + public ICodexNode AddCodex() { return AddCodex(s => { }); @@ -58,7 +61,7 @@ namespace CodexTests setup(s); OnCodexSetup(s); }); - onlineCodexNodes.AddRange(group); + onlineCodexNodes[Get()].AddRange(group); return group; } @@ -74,7 +77,7 @@ namespace CodexTests public IEnumerable GetAllOnlineCodexNodes() { - return onlineCodexNodes; + return onlineCodexNodes[Get()]; } public void AssertBalance(ICodexContracts contracts, ICodexNode codexNode, Constraint constraint, string msg = "") @@ -85,5 +88,14 @@ namespace CodexTests protected virtual void OnCodexSetup(ICodexSetup setup) { } + + protected override void CollectStatusLogData(TestLifecycle lifecycle, Dictionary data) + { + var nodes = onlineCodexNodes[lifecycle]; + var upload = nodes.Select(n => n.TransferSpeeds.GetUploadSpeed()).ToList()!.OptionalAverage(); + var download = nodes.Select(n => n.TransferSpeeds.GetDownloadSpeed()).ToList()!.OptionalAverage(); + if (upload != null) data.Add("avgupload", upload.ToString()); + if (download != null) data.Add("avgdownload", download.ToString()); + } } } diff --git a/Tests/DistTestCore/DistTest.cs b/Tests/DistTestCore/DistTest.cs index 74898d5f..06014e0c 100644 --- a/Tests/DistTestCore/DistTest.cs +++ b/Tests/DistTestCore/DistTest.cs @@ -147,6 +147,18 @@ namespace DistTestCore { } + protected virtual void LifecycleStart(TestLifecycle lifecycle) + { + } + + protected virtual void LifecycleStop(TestLifecycle lifecycle) + { + } + + protected virtual void CollectStatusLogData(TestLifecycle lifecycle, Dictionary data) + { + } + protected TestLifecycle Get() { lock (lifecycleLock) @@ -166,6 +178,7 @@ namespace DistTestCore var testNamespace = TestNamespacePrefix + Guid.NewGuid().ToString(); var lifecycle = new TestLifecycle(fixtureLog.CreateTestLog(), configuration, GetTimeSet(), testNamespace); lifecycles.Add(testName, lifecycle); + LifecycleStart(lifecycle); } }); } @@ -175,13 +188,16 @@ namespace DistTestCore var lifecycle = Get(); var testResult = GetTestResult(); var testDuration = lifecycle.GetTestDuration(); + var data = lifecycle.GetPluginMetadata(); + CollectStatusLogData(lifecycle, data); fixtureLog.Log($"{GetCurrentTestName()} = {testResult} ({testDuration})"); - statusLog.ConcludeTest(testResult, testDuration, lifecycle.GetPluginMetadata()); + statusLog.ConcludeTest(testResult, testDuration, data); Stopwatch.Measure(fixtureLog, $"Teardown for {GetCurrentTestName()}", () => { WriteEndTestLog(lifecycle.Log); IncludeLogsOnTestFailure(lifecycle); + LifecycleStop(lifecycle); lifecycle.DeleteAllResources(); lifecycle = null!; });