Logging upload/download times and adds performance threshold assertions to large-file tests.
This commit is contained in:
parent
56dc1c632d
commit
d2d7f3dea5
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -10,7 +10,6 @@ using System.Reflection;
|
|||
|
||||
namespace DistTestCore
|
||||
{
|
||||
[SetUpFixture]
|
||||
[Parallelizable(ParallelScope.All)]
|
||||
public abstract class DistTest
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,14 @@ namespace Logging
|
|||
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)
|
||||
{
|
||||
return Begin(log, "");
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
using NUnit.Framework;
|
||||
|
||||
[assembly: LevelOfParallelism(1)]
|
||||
namespace Tests
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue