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 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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, "");
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
[assembly: LevelOfParallelism(1)]
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
}
|
Loading…
Reference in New Issue