Skip to content

Commit 5b42b76

Browse files
committed
Adds streamless small-swarm test
1 parent 2afcb92 commit 5b42b76

File tree

5 files changed

+132
-30
lines changed

5 files changed

+132
-30
lines changed

Framework/Utils/Retry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private void CheckMaximums()
9898

9999
private void Fail()
100100
{
101-
throw new TimeoutException($"Retry '{description}' timed out after {tryNumber} tries over {Time.FormatDuration(Duration())}: {GetFailureReport}",
101+
throw new TimeoutException($"Retry '{description}' timed out after {tryNumber} tries over {Time.FormatDuration(Duration())}: {GetFailureReport()}",
102102
new AggregateException(failures.Select(f => f.Exception)));
103103
}
104104

ProjectPlugins/CodexPlugin/CodexNode.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public interface ICodexNode : IHasContainer, IHasMetricsScrapeTarget, IHasEthAdd
2323
TrackedFile? DownloadContent(ContentId contentId, string fileLabel = "");
2424
TrackedFile? DownloadContent(ContentId contentId, Action<Failure> onFailure, string fileLabel = "");
2525
LocalDataset DownloadStreamless(ContentId cid);
26+
/// <summary>
27+
/// TODO: This will monitor the quota-used of the node until 'size' bytes are added. That's a very bad way
28+
/// to track the streamless download progress. Replace it once we have a good API for this.
29+
/// </summary>
30+
LocalDataset DownloadStreamlessWait(ContentId cid, ByteSize size);
2631
LocalDataset DownloadManifestOnly(ContentId cid);
2732
LocalDatasetList LocalFiles();
2833
CodexSpace Space();
@@ -205,11 +210,28 @@ public ContentId UploadFile(TrackedFile file, string contentType, string content
205210

206211
public LocalDataset DownloadStreamless(ContentId cid)
207212
{
213+
Log($"Downloading streamless '{cid}' (no-wait)");
208214
return CodexAccess.DownloadStreamless(cid);
209215
}
210216

217+
public LocalDataset DownloadStreamlessWait(ContentId cid, ByteSize size)
218+
{
219+
Log($"Downloading streamless '{cid}' (wait till finished)");
220+
221+
var sw = Stopwatch.Measure(log, nameof(DownloadStreamlessWait), () =>
222+
{
223+
var startSpace = Space();
224+
var result = CodexAccess.DownloadStreamless(cid);
225+
WaitUntilQuotaUsedIncreased(startSpace, size);
226+
return result;
227+
});
228+
229+
return sw.Value;
230+
}
231+
211232
public LocalDataset DownloadManifestOnly(ContentId cid)
212233
{
234+
Log($"Downloading manifest-only '{cid}'");
213235
return CodexAccess.DownloadManifestOnly(cid);
214236
}
215237

@@ -321,6 +343,39 @@ private void DownloadToFile(string contentId, TrackedFile file, Action<Failure>
321343
}
322344
}
323345

346+
public void WaitUntilQuotaUsedIncreased(CodexSpace startSpace, ByteSize expectedIncreaseOfQuotaUsed)
347+
{
348+
WaitUntilQuotaUsedIncreased(startSpace, expectedIncreaseOfQuotaUsed, TimeSpan.FromMinutes(2));
349+
}
350+
351+
public void WaitUntilQuotaUsedIncreased(
352+
CodexSpace startSpace,
353+
ByteSize expectedIncreaseOfQuotaUsed,
354+
TimeSpan maxTimeout)
355+
{
356+
Log($"Waiting until quotaUsed " +
357+
$"(start: {startSpace.QuotaUsedBytes}) " +
358+
$"increases by {expectedIncreaseOfQuotaUsed} " +
359+
$"to reach {startSpace.QuotaUsedBytes + expectedIncreaseOfQuotaUsed.SizeInBytes}");
360+
361+
var retry = new Retry($"Checking local space for quotaUsed increase of {expectedIncreaseOfQuotaUsed}",
362+
maxTimeout: maxTimeout,
363+
sleepAfterFail: TimeSpan.FromSeconds(3),
364+
onFail: f => { });
365+
366+
retry.Run(() =>
367+
{
368+
var space = Space();
369+
var increase = space.QuotaUsedBytes - startSpace.QuotaUsedBytes;
370+
371+
if (increase < expectedIncreaseOfQuotaUsed.SizeInBytes)
372+
throw new Exception($"Expected quota-used not reached. " +
373+
$"Expected increase: {expectedIncreaseOfQuotaUsed.SizeInBytes} " +
374+
$"Actual increase: {increase} " +
375+
$"Actual used: {space.QuotaUsedBytes}");
376+
});
377+
}
378+
324379
private void EnsureMarketplace()
325380
{
326381
if (ethAccount == null) throw new Exception("Marketplace is not enabled for this Codex node. Please start it with the option '.EnableMarketplace(...)' to enable it.");

Tests/CodexReleaseTests/DataTests/StreamlessDownloadTest.cs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using CodexTests;
1+
using CodexPlugin;
2+
using CodexTests;
23
using NUnit.Framework;
4+
using System.Drawing;
35
using Utils;
46

57
namespace CodexReleaseTests.DataTests
@@ -13,31 +15,17 @@ public void StreamlessTest()
1315
var uploader = StartCodex();
1416
var downloader = StartCodex(s => s.WithBootstrapNode(uploader));
1517

16-
var file = GenerateTestFile(10.MB());
17-
var size = file.GetFilesize().SizeInBytes;
18+
var size = 10.MB();
19+
var file = GenerateTestFile(size);
1820
var cid = uploader.UploadFile(file);
1921

2022
var startSpace = downloader.Space();
2123
var start = DateTime.UtcNow;
22-
var localDataset = downloader.DownloadStreamless(cid);
24+
var localDataset = downloader.DownloadStreamlessWait(cid, size);
2325

2426
Assert.That(localDataset.Cid, Is.EqualTo(cid));
2527
Assert.That(localDataset.Manifest.OriginalBytes.SizeInBytes, Is.EqualTo(file.GetFilesize().SizeInBytes));
2628

27-
// TODO: We have no way to inspect the status or progress of the download.
28-
// We use local space information to estimate.
29-
var retry = new Retry("Checking local space",
30-
maxTimeout: TimeSpan.FromMinutes(2),
31-
sleepAfterFail: TimeSpan.FromSeconds(3),
32-
onFail: f => { });
33-
34-
retry.Run(() =>
35-
{
36-
var space = downloader.Space();
37-
var expected = startSpace.FreeBytes - size;
38-
if (space.FreeBytes > expected) throw new Exception("Expected free space not reached.");
39-
});
40-
4129
// Stop the uploader node and verify that the downloader has the data.
4230
uploader.Stop(waitTillStopped: true);
4331
var downloaded = downloader.DownloadContent(cid);

Tests/CodexReleaseTests/DataTests/SwarmTest.cs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,23 @@ public void SmallSwarm()
2424
AssertAllFilesDownloadedCorrectly(files);
2525
}
2626

27+
[Test]
28+
public void StreamlessSmallSwarm()
29+
{
30+
var nodes = StartCodex(NumberOfNodes);
31+
var files = nodes.Select(UploadUniqueFilePerNode).ToArray();
32+
33+
var tasks = ParallelStreamlessDownloadEachFile(nodes, files);
34+
Task.WaitAll(tasks);
35+
36+
AssertAllFilesStreamlesslyDownloadedCorrectly(nodes, files);
37+
}
38+
2739
private SwarmTestNetworkFile UploadUniqueFilePerNode(ICodexNode node)
2840
{
2941
var file = GenerateTestFile(FileSizeMb.MB());
3042
var cid = node.UploadFile(file);
31-
return new SwarmTestNetworkFile(file, cid);
43+
return new SwarmTestNetworkFile(node, file, cid);
3244
}
3345

3446
private Task[] ParallelDownloadEachFile(ICodexNodeGroup nodes, SwarmTestNetworkFile[] files)
@@ -43,6 +55,18 @@ private Task[] ParallelDownloadEachFile(ICodexNodeGroup nodes, SwarmTestNetworkF
4355
return tasks.ToArray();
4456
}
4557

58+
private Task[] ParallelStreamlessDownloadEachFile(ICodexNodeGroup nodes, SwarmTestNetworkFile[] files)
59+
{
60+
var tasks = new List<Task>();
61+
62+
foreach (var node in nodes)
63+
{
64+
tasks.Add(StartStreamlessDownload(node, files));
65+
}
66+
67+
return tasks.ToArray();
68+
}
69+
4670
private Task StartDownload(ICodexNode node, SwarmTestNetworkFile[] files)
4771
{
4872
return Task.Run(() =>
@@ -68,6 +92,31 @@ private Task StartDownload(ICodexNode node, SwarmTestNetworkFile[] files)
6892
});
6993
}
7094

95+
private Task StartStreamlessDownload(ICodexNode node, SwarmTestNetworkFile[] files)
96+
{
97+
return Task.Run(() =>
98+
{
99+
var remaining = files.ToList();
100+
101+
while (remaining.Count > 0)
102+
{
103+
var file = remaining.PickOneRandom();
104+
if (file.Uploader.GetName() != node.GetName())
105+
{
106+
try
107+
{
108+
var startSpace = node.Space();
109+
node.DownloadStreamlessWait(file.Cid, FileSizeMb.MB());
110+
}
111+
catch (Exception ex)
112+
{
113+
file.Error = ex;
114+
}
115+
}
116+
}
117+
});
118+
}
119+
71120
private void AssertAllFilesDownloadedCorrectly(SwarmTestNetworkFile[] files)
72121
{
73122
foreach (var file in files)
@@ -83,14 +132,32 @@ private void AssertAllFilesDownloadedCorrectly(SwarmTestNetworkFile[] files)
83132
}
84133
}
85134

135+
private void AssertAllFilesStreamlesslyDownloadedCorrectly(ICodexNodeGroup nodes, SwarmTestNetworkFile[] files)
136+
{
137+
var totalFilesSpace = 0.Bytes();
138+
foreach (var file in files)
139+
{
140+
if (file.Error != null) throw file.Error;
141+
totalFilesSpace = new ByteSize(totalFilesSpace.SizeInBytes + file.Original.GetFilesize().SizeInBytes);
142+
}
143+
144+
foreach (var node in nodes)
145+
{
146+
var currentSpace = node.Space();
147+
Assert.That(currentSpace.QuotaUsedBytes, Is.GreaterThanOrEqualTo(totalFilesSpace.SizeInBytes));
148+
}
149+
}
150+
86151
private class SwarmTestNetworkFile
87152
{
88-
public SwarmTestNetworkFile(TrackedFile original, ContentId cid)
153+
public SwarmTestNetworkFile(ICodexNode uploader, TrackedFile original, ContentId cid)
89154
{
155+
Uploader = uploader;
90156
Original = original;
91157
Cid = cid;
92158
}
93159

160+
public ICodexNode Uploader { get; }
94161
public TrackedFile Original { get; }
95162
public ContentId Cid { get; }
96163
public object Lock { get; } = new object();

Tests/ExperimentalTests/CodexDistTest.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using NUnit.Framework;
1616
using NUnit.Framework.Constraints;
1717
using OverwatchTranscript;
18+
using Utils;
1819

1920
namespace CodexTests
2021
{
@@ -155,15 +156,6 @@ private string GetBasicNodeStatus(ICodexNode node)
155156
node.Space().ToString() + Environment.NewLine;
156157
}
157158

158-
// Disabled for now: Makes huge log files!
159-
//private string GetNodeMetrics(IMetricsAccess? metrics)
160-
//{
161-
// if (metrics == null) return "No metrics enabled";
162-
// var m = metrics.GetAllMetrics();
163-
// if (m == null) return "No metrics received";
164-
// return m.AsCsv();
165-
//}
166-
167159
protected virtual void OnCodexSetup(ICodexSetup setup)
168160
{
169161
}

0 commit comments

Comments
 (0)