Logging upload/download times and adds performance threshold assertions to large-file tests.

This commit is contained in:
benbierens 2023-06-07 08:30:10 +02:00
parent 56dc1c632d
commit d2d7f3dea5
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
9 changed files with 71 additions and 40 deletions

View File

@ -12,6 +12,11 @@
public long SizeInBytes { get; } public long SizeInBytes { get; }
public long ToMB()
{
return SizeInBytes / (1024 * 1024);
}
public override bool Equals(object? obj) public override bool Equals(object? obj)
{ {
return obj is ByteSize size && SizeInBytes == size.SizeInBytes; return obj is ByteSize size && SizeInBytes == size.SizeInBytes;

View File

@ -14,6 +14,10 @@ namespace DistTestCore.Codex
public const string MetricsPortTag = "metrics_port"; public const string MetricsPortTag = "metrics_port";
public const string DiscoveryPortTag = "discovery-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 string Image => DockerImage;
protected override void Initialize(StartupConfig startupConfig) protected override void Initialize(StartupConfig startupConfig)

View File

@ -10,7 +10,6 @@ using System.Reflection;
namespace DistTestCore namespace DistTestCore
{ {
[SetUpFixture]
[Parallelizable(ParallelScope.All)] [Parallelizable(ParallelScope.All)]
public abstract class DistTest public abstract class DistTest
{ {

View File

@ -1,4 +1,5 @@
using NUnit.Framework; using DistTestCore.Codex;
using NUnit.Framework;
namespace DistTestCore.Helpers 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()))}"); test.Log($"Success! Full download interconnectivity for nodes: {string.Join(",", nodes.Select(n => n.GetName()))}");
var timeTaken = DateTime.UtcNow - start; 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 numberOfDownloads = numberOfNodes * (numberOfNodes - 1);
var timePerDownload = timeTaken / numberOfDownloads; var timePerDownload = timeTaken / numberOfDownloads;
float sizeInMB = size.SizeInBytes / (1024.0f * 1024.0f); float sizeInMB = size.ToMB();
var timePerMB = timePerDownload.TotalSeconds / sizeInMB; 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} seconds per MB.");
var maxTimePerMB = 2.0f; Assert.That(timePerMB, Is.LessThan(CodexContainerRecipe.MaxDownloadTimePerMegabyte), "MaxDownloadTimePerMegabyte performance threshold breached.");
Assert.That(timePerMB, Is.LessThan(maxTimePerMB), "Seconds-per-MB performance threshold breached.");
} }
private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize) private void PerformTest(IOnlineCodexNode uploader, IOnlineCodexNode[] downloaders, ByteSize testFileSize)

View File

@ -2,6 +2,7 @@
using DistTestCore.Logs; using DistTestCore.Logs;
using DistTestCore.Marketplace; using DistTestCore.Marketplace;
using DistTestCore.Metrics; using DistTestCore.Metrics;
using Logging;
using NUnit.Framework; using NUnit.Framework;
namespace DistTestCore namespace DistTestCore
@ -66,9 +67,14 @@ namespace DistTestCore
public ContentId UploadFile(TestFile file) public ContentId UploadFile(TestFile file)
{ {
Log($"Uploading file '{file.Describe()}' of size {file.GetFileSize()}...");
using var fileStream = File.OpenRead(file.Filename); 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)) if (response.StartsWith(UploadFailedMessage))
{ {
Assert.Fail("Node failed to store block."); Assert.Fail("Node failed to store block.");
@ -82,9 +88,9 @@ namespace DistTestCore
public TestFile? DownloadContent(ContentId contentId, string fileLabel = "") 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); 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}'."); Log($"Downloaded file '{file.Describe()}' of size {file.GetFileSize()} to '{file.Filename}'.");
return file; return file;
} }

View File

@ -23,6 +23,14 @@ namespace Logging
sw.End(); sw.End();
} }
public static T Measure<T>(BaseLog log, string name, Func<T> action, bool debug = false)
{
var sw = Begin(log, name, debug);
var result = action();
sw.End();
return result;
}
public static Stopwatch Begin(BaseLog log) public static Stopwatch Begin(BaseLog log)
{ {
return Begin(log, ""); return Begin(log, "");

View File

@ -6,25 +6,6 @@ namespace TestsLong.BasicTests
[TestFixture] [TestFixture]
public class DownloadTests : DistTest 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(3, 500)]
[TestCase(5, 100)] [TestCase(5, 100)]
[TestCase(10, 256)] [TestCase(10, 256)]

View File

@ -1,4 +1,5 @@
using DistTestCore; using DistTestCore;
using DistTestCore.Codex;
using NUnit.Framework; using NUnit.Framework;
namespace TestsLong.BasicTests namespace TestsLong.BasicTests
@ -6,19 +7,41 @@ namespace TestsLong.BasicTests
[TestFixture] [TestFixture]
public class LargeFileTests : DistTest public class LargeFileTests : DistTest
{ {
[Test, UseLongTimeouts] [Test]
public void OneClientLargeFileTest() [Combinatorial]
[UseLongTimeouts]
public void DownloadCorrectnessTest(
[Values(1, 10, 100, 1024)] int sizeInMB,
[Values(1, 10, 100, 1024)] int multiplier)
{ {
var primary = SetupCodexNode(s => s var size = (sizeInMB * multiplier).MB();
.WithStorageQuota(20.GB()));
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);
} }
} }
} }

6
LongTests/Parallelism.cs Normal file
View File

@ -0,0 +1,6 @@
using NUnit.Framework;
[assembly: LevelOfParallelism(1)]
namespace Tests
{
}