using CodexPlugin; using DistTestCore; using FileUtils; using NUnit.Framework; using Utils; namespace CodexTests.ScalabilityTests; [TestFixture] public class ScalabilityTests : CodexDistTest { /// /// We upload a file to node A, then download it with B. /// Then we stop node A, and download again with node C. /// [Test] [Combinatorial] [UseLongTimeouts] [DontDownloadLogs] [WaitForCleanup] public void ShouldMaintainFileInNetwork( [Values(4, 5, 6)] int numberOfNodes, // TODO: include 10, 40, 80 and 100, not 5 [Values(4000, 5000, 6000, 7000, 8000, 9000, 10000)] int fileSizeInMb ) { var logLevel = CodexLogLevel.Trace; var bootstrap = StartCodex(s => s.WithLogLevel(logLevel)); var nodes = StartCodex(numberOfNodes - 1, s => s .WithBootstrapNode(bootstrap) .WithLogLevel(logLevel) .WithStorageQuota((fileSizeInMb + 50).MB()) ).ToList(); var uploader = nodes.PickOneRandom(); var downloader = nodes.PickOneRandom(); var testFile = GenerateTestFile(fileSizeInMb.MB()); LogNodeStatus(uploader); var contentId = uploader.UploadFile(testFile, f => LogNodeStatus(uploader)); LogNodeStatus(uploader); LogNodeStatus(downloader); var downloadedFile = downloader.DownloadContent(contentId, f => LogNodeStatus(downloader)); LogNodeStatus(downloader); downloadedFile!.AssertIsEqual(testFile); uploader.DeleteRepoFolder(); uploader.Stop(true); var otherDownloader = nodes.PickOneRandom(); downloadedFile = otherDownloader.DownloadContent(contentId); downloadedFile!.AssertIsEqual(testFile); downloader.DeleteRepoFolder(); otherDownloader.DeleteRepoFolder(); } /// /// We upload a file to each node, to put a more wide-spread load on the network. /// Then we run the same test as ShouldMaintainFileInNetwork. /// [Ignore("Fix ShouldMaintainFileInNetwork for all values first")] [Test] [Combinatorial] [UseLongTimeouts] [DontDownloadLogs] [WaitForCleanup] public void EveryoneGetsAFile( [Values(10, 40, 80, 100)] int numberOfNodes, [Values(100, 1000, 5000, 10000)] int fileSizeInMb ) { var logLevel = CodexLogLevel.Info; var bootstrap = StartCodex(s => s.WithLogLevel(logLevel)); var nodes = StartCodex(numberOfNodes - 1, s => s .WithBootstrapNode(bootstrap) .WithLogLevel(logLevel) .WithStorageQuota((fileSizeInMb + 50).MB()) ).ToList(); var pairTasks = nodes.Select(n => { return Task.Run(() => { var file = GenerateTestFile(fileSizeInMb.MB()); var cid = n.UploadFile(file); return new NodeFilePair(n, file, cid); }); }); var pairs = pairTasks.Select(t => Time.Wait(t)).ToList(); RunDoubleDownloadTest( pairs.PickOneRandom(), pairs.PickOneRandom(), pairs.PickOneRandom() ); } private void RunDoubleDownloadTest(NodeFilePair source, NodeFilePair dl1, NodeFilePair dl2) { var expectedFile = source.File; var cid = source.Cid; var file1 = dl1.Node.DownloadContent(cid); file1!.AssertIsEqual(expectedFile); source.Node.Stop(true); var file2 = dl2.Node.DownloadContent(cid); file2!.AssertIsEqual(expectedFile); } public class NodeFilePair { public NodeFilePair(ICodexNode node, TrackedFile file, ContentId cid) { Node = node; File = file; Cid = cid; } public ICodexNode Node { get; } public TrackedFile File { get; } public ContentId Cid { get; } } }