From 074f5ebfaeded1eca0f166dd09e7911040619ea4 Mon Sep 17 00:00:00 2001 From: benbierens Date: Wed, 6 Dec 2023 09:59:45 +0100 Subject: [PATCH] Sets up transferSpeed class --- Framework/FileUtils/TrackedFile.cs | 5 ++ Framework/Logging/Stopwatch.cs | 22 ++++++-- Framework/Utils/ByteSize.cs | 7 +++ ProjectPlugins/CodexPlugin/CodexNode.cs | 12 ++++- ProjectPlugins/CodexPlugin/TransferSpeeds.cs | 52 +++++++++++++++++++ .../Helpers/PeerDownloadTestHelpers.cs | 6 +-- 6 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 ProjectPlugins/CodexPlugin/TransferSpeeds.cs diff --git a/Framework/FileUtils/TrackedFile.cs b/Framework/FileUtils/TrackedFile.cs index 5f9b04a..694408b 100644 --- a/Framework/FileUtils/TrackedFile.cs +++ b/Framework/FileUtils/TrackedFile.cs @@ -37,6 +37,11 @@ namespace FileUtils return $"'{Filename}'{sizePostfix}"; } + public ByteSize GetFilesize() + { + return new ByteSize(GetFileSize()); + } + private void AssertEqual(TrackedFile? actual) { if (actual == null) FrameworkAssert.Fail("TestFile is null."); diff --git a/Framework/Logging/Stopwatch.cs b/Framework/Logging/Stopwatch.cs index fddd8b5..d2f13b1 100644 --- a/Framework/Logging/Stopwatch.cs +++ b/Framework/Logging/Stopwatch.cs @@ -16,19 +16,19 @@ namespace Logging this.debug = debug; } - public static void Measure(ILog log, string name, Action action, bool debug = false) + public static TimeSpan Measure(ILog log, string name, Action action, bool debug = false) { var sw = Begin(log, name, debug); action(); - sw.End(); + return sw.End(); } - public static T Measure(ILog log, string name, Func action, bool debug = false) + public static StopwatchResult Measure(ILog log, string name, Func action, bool debug = false) { var sw = Begin(log, name, debug); var result = action(); - sw.End(); - return result; + var duration = sw.End(); + return new StopwatchResult(result, duration); } public static Stopwatch Begin(ILog log) @@ -68,4 +68,16 @@ namespace Logging return duration; } } + + public class StopwatchResult + { + public StopwatchResult(T value, TimeSpan duration) + { + Value = value; + Duration = duration; + } + + public T Value { get; } + public TimeSpan Duration { get; } + } } diff --git a/Framework/Utils/ByteSize.cs b/Framework/Utils/ByteSize.cs index 170aaf7..69d5f91 100644 --- a/Framework/Utils/ByteSize.cs +++ b/Framework/Utils/ByteSize.cs @@ -46,6 +46,13 @@ } } + public class BytesPerSecond : ByteSize + { + public BytesPerSecond(long sizeInBytes) : base(sizeInBytes) + { + } + } + public static class ByteSizeIntExtensions { private const long Kilo = 1024; diff --git a/ProjectPlugins/CodexPlugin/CodexNode.cs b/ProjectPlugins/CodexPlugin/CodexNode.cs index d0a0636..2c79459 100644 --- a/ProjectPlugins/CodexPlugin/CodexNode.cs +++ b/ProjectPlugins/CodexPlugin/CodexNode.cs @@ -25,6 +25,7 @@ namespace CodexPlugin IMarketplaceAccess Marketplace { get; } CrashWatcher CrashWatcher { get; } PodInfo GetPodInfo(); + ITransferSpeeds TransferSpeeds { get; } void Stop(); } @@ -34,6 +35,7 @@ namespace CodexPlugin private const string UploadFailedMessage = "Unable to store block"; private readonly IPluginTools tools; private readonly EthAddress? ethAddress; + private readonly TransferSpeeds transferSpeeds; public CodexNode(IPluginTools tools, CodexAccess codexAccess, CodexNodeGroup group, IMarketplaceAccess marketplaceAccess, EthAddress? ethAddress) { @@ -43,6 +45,7 @@ namespace CodexPlugin Group = group; Marketplace = marketplaceAccess; Version = new CodexDebugVersionResponse(); + transferSpeeds = new TransferSpeeds(); } public RunningContainer Container { get { return CodexAccess.Container; } } @@ -51,6 +54,7 @@ namespace CodexPlugin public CodexNodeGroup Group { get; } public IMarketplaceAccess Marketplace { get; } public CodexDebugVersionResponse Version { get; private set; } + public ITransferSpeeds TransferSpeeds { get => transferSpeeds; } public IMetricsScrapeTarget MetricsScrapeTarget { get @@ -101,11 +105,14 @@ namespace CodexPlugin var logMessage = $"Uploading file {file.Describe()}..."; Log(logMessage); - var response = Stopwatch.Measure(tools.GetLog(), logMessage, () => + var measurement = Stopwatch.Measure(tools.GetLog(), logMessage, () => { return CodexAccess.UploadFile(fileStream); }); + var response = measurement.Value; + transferSpeeds.AddUploadSample(file.GetFilesize(), measurement.Duration); + if (string.IsNullOrEmpty(response)) FrameworkAssert.Fail("Received empty response."); if (response.StartsWith(UploadFailedMessage)) FrameworkAssert.Fail("Node failed to store block."); @@ -118,7 +125,8 @@ namespace CodexPlugin var logMessage = $"Downloading for contentId: '{contentId.Id}'..."; Log(logMessage); var file = tools.GetFileManager().CreateEmptyFile(fileLabel); - Stopwatch.Measure(tools.GetLog(), logMessage, () => DownloadToFile(contentId.Id, file)); + var measurement = Stopwatch.Measure(tools.GetLog(), logMessage, () => DownloadToFile(contentId.Id, file)); + transferSpeeds.AddDownloadSample(file.GetFilesize(), measurement); Log($"Downloaded file {file.Describe()} to '{file.Filename}'."); return file; } diff --git a/ProjectPlugins/CodexPlugin/TransferSpeeds.cs b/ProjectPlugins/CodexPlugin/TransferSpeeds.cs new file mode 100644 index 0000000..ae1f291 --- /dev/null +++ b/ProjectPlugins/CodexPlugin/TransferSpeeds.cs @@ -0,0 +1,52 @@ +using Utils; + +namespace CodexPlugin +{ + public interface ITransferSpeeds + { + BytesPerSecond GetUploadSpeed(); + BytesPerSecond GetDownloadSpeed(); + } + + public class TransferSpeeds : ITransferSpeeds + { + private readonly List uploads = new List(); + private readonly List downloads = new List(); + + public void AddUploadSample(ByteSize bytes, TimeSpan duration) + { + uploads.Add(Convert(bytes, duration)); + } + + public void AddDownloadSample(ByteSize bytes, TimeSpan duration) + { + downloads.Add(Convert(bytes, duration)); + } + + public BytesPerSecond GetUploadSpeed() + { + return Average(uploads); + } + + public BytesPerSecond GetDownloadSpeed() + { + return Average(downloads); + } + + private static BytesPerSecond Convert(ByteSize size, TimeSpan duration) + { + double bytes = size.SizeInBytes; + double seconds = duration.TotalSeconds; + + return new BytesPerSecond(System.Convert.ToInt64(Math.Round(bytes / seconds))); + } + + private static BytesPerSecond Average(List list) + { + double sum = list.Sum(i => i.SizeInBytes); + double num = list.Count; + + return new BytesPerSecond(System.Convert.ToInt64(Math.Round(sum / num))); + } + } +} diff --git a/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs b/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs index fab2a23..6dab12a 100644 --- a/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs +++ b/Tests/CodexTests/Helpers/PeerDownloadTestHelpers.cs @@ -9,7 +9,6 @@ namespace CodexTests.Helpers public class PeerDownloadTestHelpers : IFullConnectivityImplementation { private readonly FullConnectivityHelper helper; - private readonly ILog log; private readonly IFileManager fileManager; private ByteSize testFileSize; @@ -17,7 +16,6 @@ namespace CodexTests.Helpers { helper = new FullConnectivityHelper(log, this); testFileSize = 1.MB(); - this.log = log; this.fileManager = fileManager; } @@ -45,11 +43,11 @@ namespace CodexTests.Helpers private PeerConnectionState CheckConnectivity(Entry from, Entry to) { var expectedFile = GenerateTestFile(from.Node, to.Node); - var contentId = Stopwatch.Measure(log, "Upload", () => from.Node.UploadFile(expectedFile)); + var contentId = from.Node.UploadFile(expectedFile); try { - var downloadedFile = Stopwatch.Measure(log, "Download", () => DownloadFile(to.Node, contentId, expectedFile.Label + "_downloaded")); + var downloadedFile = DownloadFile(to.Node, contentId, expectedFile.Label + "_downloaded"); expectedFile.AssertIsEqual(downloadedFile); return PeerConnectionState.Connection; }