Compare commits

...
8 changed files with 147 additions and 180 deletions
@@ -9,7 +9,7 @@ namespace CodexPlugin
public CodexDeployment(CodexInstance[] codexInstances, GethDeployment gethDeployment,
CodexContractsDeployment codexContractsDeployment, RunningContainers? prometheusContainer,
RunningContainers? discordBotContainer, DeploymentMetadata metadata,
String id)
string id)
{
Id = id;
CodexInstances = codexInstances;
@@ -20,7 +20,7 @@ namespace CodexPlugin
Metadata = metadata;
}
public String Id { get; }
public string Id { get; }
public CodexInstance[] CodexInstances { get; }
public GethDeployment GethDeployment { get; }
public CodexContractsDeployment CodexContractsDeployment { get; }
+23 -7
View File
@@ -1,7 +1,8 @@
using CodexPlugin;
using CodexContractsPlugin;
using CodexPlugin;
using Core;
using DistTestCore;
using FileUtils;
using GethPlugin;
using Logging;
using MetricsPlugin;
@@ -32,7 +33,7 @@ namespace ContinuousTests
if (nodes != null)
{
NodeRunner = new NodeRunner(Nodes, configuration, Log, CustomK8sNamespace);
NodeRunner = new NodeRunner(Nodes, configuration, Log);
}
else
{
@@ -57,15 +58,23 @@ namespace ContinuousTests
{
if (Configuration.CodexDeployment.PrometheusContainer == null) throw new Exception("Expected prometheus to be part of Codex deployment.");
var entryPointFactory = new EntryPointFactory();
var entryPoint = entryPointFactory.CreateEntryPoint(Configuration.KubeConfigFile, Configuration.DataPath, Configuration.CodexDeployment.Metadata.KubeNamespace, Log);
return entryPoint.CreateInterface().WrapMetricsCollector(Configuration.CodexDeployment.PrometheusContainer, target);
var ci = CreateCi();
return ci.WrapMetricsCollector(Configuration.CodexDeployment.PrometheusContainer, target);
}
public (IGethNode, ICodexContracts) CreateMarketplaceAccess()
{
var ci = CreateCi();
var geth = ci.WrapGethDeployment(Configuration.CodexDeployment.GethDeployment);
var contracts = ci.WrapCodexContractsDeployment(geth, Configuration.CodexDeployment.CodexContractsDeployment);
return (geth, contracts);
}
public abstract int RequiredNumberOfNodes { get; }
public abstract TimeSpan RunTestEvery { get; }
public abstract TestFailMode TestFailMode { get; }
public virtual string CustomK8sNamespace { get { return string.Empty; } }
public string Name
{
@@ -74,6 +83,13 @@ namespace ContinuousTests
return GetType().Name;
}
}
private CoreInterface CreateCi()
{
var entryPointFactory = new EntryPointFactory();
var entryPoint = entryPointFactory.CreateEntryPoint(Configuration.KubeConfigFile, Configuration.DataPath, Configuration.CodexDeployment.Metadata.KubeNamespace, Log);
return entryPoint.CreateInterface();
}
}
public enum TestFailMode
@@ -51,8 +51,6 @@ namespace ContinuousTests
overviewLog.Log("");
var allTests = testFactory.CreateTests();
ClearAllCustomNamespaces(allTests, overviewLog);
var filteredTests = FilterTests(allTests, overviewLog);
if (!filteredTests.Any())
{
@@ -136,21 +134,6 @@ namespace ContinuousTests
return result;
}
private void ClearAllCustomNamespaces(ContinuousTest[] allTests, ILog log)
{
foreach (var test in allTests) ClearAllCustomNamespaces(test, log);
}
private void ClearAllCustomNamespaces(ContinuousTest test, ILog log)
{
if (string.IsNullOrEmpty(test.CustomK8sNamespace)) return;
log.Log($"Clearing namespace '{test.CustomK8sNamespace}'...");
var entryPoint = entryPointFactory.CreateEntryPoint(config.KubeConfigFile, config.DataPath, test.CustomK8sNamespace, log);
entryPoint.Tools.CreateWorkflow().DeleteNamespacesStartingWith(test.CustomK8sNamespace);
}
private void PerformCleanup(ILog log)
{
if (!config.Cleanup) return;
@@ -25,7 +25,6 @@ namespace ContinuousTests
);
return new EntryPoint(log, lifecycleConfig, dataFilePath);
//DefaultContainerRecipe.TestsType = "continuous-tests";
}
private static string? GetKubeConfig(string kubeConfigFile)
+19 -23
View File
@@ -13,14 +13,12 @@ namespace ContinuousTests
private readonly ICodexNode[] nodes;
private readonly Configuration config;
private readonly ILog log;
private readonly string customNamespace;
public NodeRunner(ICodexNode[] nodes, Configuration config, ILog log, string customNamespace)
public NodeRunner(ICodexNode[] nodes, Configuration config, ILog log)
{
this.nodes = nodes;
this.config = config;
this.log = log;
this.customNamespace = customNamespace;
}
public IDownloadedLog DownloadLog(RunningContainer container, int? tailLines = null)
@@ -41,36 +39,34 @@ namespace ContinuousTests
// Therefore, we use the image of the bootstrap node.
CodexContainerRecipe.DockerImageOverride = bootstrapNode.Container.Recipe.Image;
var debugInfo = bootstrapNode.GetDebugInfo();
Assert.That(!string.IsNullOrEmpty(debugInfo.spr));
var node = entryPoint.CreateInterface().StartCodexNode(s =>
{
setup(s);
s.WithBootstrapNode(bootstrapNode);
});
try
{
var debugInfo = bootstrapNode.GetDebugInfo();
Assert.That(!string.IsNullOrEmpty(debugInfo.spr));
var node = entryPoint.CreateInterface().StartCodexNode(s =>
{
setup(s);
s.WithBootstrapNode(bootstrapNode);
});
try
{
operation(node);
}
catch
{
DownloadLog(node.Container);
throw;
}
operation(node);
}
catch
{
DownloadLog(node.Container);
node.Stop();
throw;
}
finally
{
entryPoint.Tools.CreateWorkflow().DeleteNamespace();
node.Stop();
}
}
private EntryPoint CreateEntryPoint()
{
return entryPointFactory.CreateEntryPoint(config.KubeConfigFile, config.DataPath, customNamespace, log);
return entryPointFactory.CreateEntryPoint(config.KubeConfigFile, config.DataPath, config.CodexDeployment.Metadata.KubeNamespace, log);
}
}
}
@@ -1,64 +1,68 @@
//using DistTestCore;
//using DistTestCore.Codex;
//using Newtonsoft.Json;
//using NUnit.Framework;
//using Utils;
using CodexContractsPlugin;
using CodexPlugin;
using FileUtils;
using NUnit.Framework;
using Utils;
//namespace ContinuousTests.Tests
//{
// public class MarketplaceTest : ContinuousTest
// {
// public override int RequiredNumberOfNodes => 1;
// public override TimeSpan RunTestEvery => TimeSpan.FromMinutes(10);
// public override TestFailMode TestFailMode => TestFailMode.StopAfterFirstFailure;
// public override int EthereumAccountIndex => 200;
// public override string CustomK8sNamespace => "codex-continuous-marketplace";
// private readonly uint numberOfSlots = 3;
// private readonly ByteSize fileSize = 10.MB();
// private readonly TestToken pricePerSlotPerSecond = 10.TestTokens();
/// manual test locally.
// private TestFile file = null!;
// private ContentId? cid;
// private string purchaseId = string.Empty;
// [TestMoment(t: Zero)]
// public void NodePostsStorageRequest()
// {
// var contractDuration = TimeSpan.FromMinutes(8);
// decimal totalDurationSeconds = Convert.ToDecimal(contractDuration.TotalSeconds);
// var expectedTotalCost = numberOfSlots * pricePerSlotPerSecond.Amount * (totalDurationSeconds + 1) * 1000000;
namespace ContinuousTests.Tests
{
public class MarketplaceTest : ContinuousTest
{
public override int RequiredNumberOfNodes => 1;
public override TimeSpan RunTestEvery => TimeSpan.FromMinutes(10);
public override TestFailMode TestFailMode => TestFailMode.StopAfterFirstFailure;
// file = FileManager.GenerateTestFile(fileSize);
private readonly uint numberOfSlots = 3;
private readonly ByteSize fileSize = 10.MB();
private readonly TestToken pricePerSlotPerSecond = 10.TestTokens();
// NodeRunner.RunNode((codexAccess, marketplaceAccess) =>
// {
// cid = UploadFile(codexAccess.Node, file);
// Assert.That(cid, Is.Not.Null);
private TrackedFile file = null!;
private ContentId? cid;
private string purchaseId = string.Empty;
// purchaseId = marketplaceAccess.RequestStorage(
// contentId: cid!,
// pricePerSlotPerSecond: pricePerSlotPerSecond,
// requiredCollateral: 100.TestTokens(),
// minRequiredNumberOfNodes: numberOfSlots,
// proofProbability: 10,
// duration: contractDuration);
[TestMoment(t: Zero)]
public void NodePostsStorageRequest()
{
var contractDuration = TimeSpan.FromMinutes(8);
decimal totalDurationSeconds = Convert.ToDecimal(contractDuration.TotalSeconds);
var expectedTotalCost = numberOfSlots * pricePerSlotPerSecond.Amount * (totalDurationSeconds + 1) * 1000000;
// Assert.That(!string.IsNullOrEmpty(purchaseId));
file = FileManager.GenerateFile(fileSize);
// WaitForContractToStart(codexAccess, purchaseId);
// });
// }
NodeRunner.RunNode(
s => s.WithName("Buyer"),
node =>
{
cid = node.UploadFile(file);
Assert.That(cid, Is.Not.Null);
// [TestMoment(t: MinuteFive + MinuteOne)]
// public void StoredDataIsAvailableAfterThreeDays()
// {
// NodeRunner.RunNode((codexAccess, marketplaceAccess) =>
// {
// var result = DownloadFile(codexAccess.Node, cid!);
purchaseId = node.Marketplace.RequestStorage(
contentId: cid!,
pricePerSlotPerSecond: pricePerSlotPerSecond,
requiredCollateral: 100.TestTokens(),
minRequiredNumberOfNodes: numberOfSlots,
proofProbability: 10,
duration: contractDuration);
// file.AssertIsEqual(result);
// });
// }
// }
//}
Assert.That(!string.IsNullOrEmpty(purchaseId));
WaitForContractToStart(codexAccess, purchaseId);
});
}
[TestMoment(t: MinuteFive + MinuteOne)]
public void StoredDataIsAvailableAfterThreeDays()
{
NodeRunner.RunNode((codexAccess, marketplaceAccess) =>
{
var result = DownloadFile(codexAccess.Node, cid!);
file.AssertIsEqual(result);
});
}
}
}
@@ -1,54 +1,51 @@
//using DistTestCore;
//using DistTestCore.Codex;
//using NUnit.Framework;
using CodexPlugin;
using FileUtils;
using NUnit.Framework;
using Utils;
//namespace ContinuousTests.Tests
//{
// public class TransientNodeTest : ContinuousTest
// {
// public override int RequiredNumberOfNodes => 3;
// public override TimeSpan RunTestEvery => TimeSpan.FromMinutes(1);
// public override TestFailMode TestFailMode => TestFailMode.StopAfterFirstFailure;
// public override string CustomK8sNamespace => nameof(TransientNodeTest).ToLowerInvariant();
// public override int EthereumAccountIndex => 201;
namespace ContinuousTests.Tests
{
public class TransientNodeTest : ContinuousTest
{
public override int RequiredNumberOfNodes => 3;
public override TimeSpan RunTestEvery => TimeSpan.FromMinutes(1);
public override TestFailMode TestFailMode => TestFailMode.StopAfterFirstFailure;
public override string CustomK8sNamespace => nameof(TransientNodeTest).ToLowerInvariant();
// private TestFile file = null!;
// private ContentId cid = null!;
private TrackedFile file = null!;
private ContentId cid = null!;
// private CodexAccess UploadBootstapNode { get { return Nodes[0]; } }
// private CodexAccess DownloadBootstapNode { get { return Nodes[1]; } }
// private CodexAccess IntermediateNode { get { return Nodes[2]; } }
private ICodexNode UploadBootstapNode { get { return Nodes[0]; } }
private ICodexNode DownloadBootstapNode { get { return Nodes[1]; } }
private ICodexNode IntermediateNode { get { return Nodes[2]; } }
// [TestMoment(t: 0)]
// public void UploadWithTransientNode()
// {
// file = FileManager.GenerateTestFile(10.MB());
[TestMoment(t: 0)]
public void UploadWithTransientNode()
{
file = FileManager.GenerateFile(10.MB());
// NodeRunner.RunNode(UploadBootstapNode, (codexAccess, marketplaceAccess, lifecycle) =>
// {
// cid = UploadFile(codexAccess, file)!;
// Assert.That(cid, Is.Not.Null);
NodeRunner.RunNode(UploadBootstapNode,
s => s.WithName("TransientUploader"),
node =>
{
cid = node.UploadFile(file);
Assert.That(cid, Is.Not.Null);
// var dlt = Task.Run(() =>
// {
// Thread.Sleep(10000);
// lifecycle.DownloadLog(codexAccess.Container);
// });
var resultFile = IntermediateNode.DownloadContent(cid);
file.AssertIsEqual(resultFile);
});
}
// var resultFile = DownloadFile(IntermediateNode, cid);
// dlt.Wait();
// file.AssertIsEqual(resultFile);
// });
// }
// [TestMoment(t: 30)]
// public void DownloadWithTransientNode()
// {
// NodeRunner.RunNode(DownloadBootstapNode, (codexAccess, marketplaceAccess, lifecycle) =>
// {
// var resultFile = DownloadFile(codexAccess, cid);
// file.AssertIsEqual(resultFile);
// });
// }
// }
//}
[TestMoment(t: MinuteOne)]
public void DownloadWithTransientNode()
{
NodeRunner.RunNode(DownloadBootstapNode,
s => s.WithName("TransientDownloader"),
node =>
{
var resultFile = node.DownloadContent(cid);
file.AssertIsEqual(resultFile);
});
}
}
}
@@ -1,7 +1,6 @@
using CodexPlugin;
using FileUtils;
using Logging;
using Newtonsoft.Json;
using NUnit.Framework;
using Utils;
@@ -22,9 +21,6 @@ namespace ContinuousTests.Tests
[TestMoment(t: Zero)]
public void UploadTestFile()
{
LogBlockExchangeStatus(Nodes[0], "Before upload");
LogBlockExchangeStatus(Nodes[1], "Before upload");
file = FileManager.GenerateFile(size);
LogStoredBytes(Nodes[0]);
@@ -38,27 +34,9 @@ namespace ContinuousTests.Tests
{
TrackedFile? dl = null;
try
{
LogBytesPerMillisecond(() => dl = Nodes[1].DownloadContent(cid!));
LogBytesPerMillisecond(() => dl = Nodes[1].DownloadContent(cid!));
file.AssertIsEqual(dl);
}
catch
{
LogRepoStore(Nodes[0]);
LogRepoStore(Nodes[1]);
throw;
}
LogBlockExchangeStatus(Nodes[0], "After download");
LogBlockExchangeStatus(Nodes[1], "After download");
}
private void LogRepoStore(ICodexNode codexNode)
{
//var response = codexNode.GetDebugRepoStore();
//Log.Log($"{codexNode.GetName()} has {string.Join(",", response.Select(r => r.cid))}");
file.AssertIsEqual(dl);
}
private void LogStoredBytes(ICodexNode node)
@@ -87,11 +65,5 @@ namespace ContinuousTests.Tests
var bytesPerMs = totalBytes / totalMs;
Log.Log($"Bytes per millisecond: {bytesPerMs}");
}
private void LogBlockExchangeStatus(ICodexNode codexNode, string msg)
{
//var response = codexNode.GetDebugBlockExchange();
//Log.Log($"{codexNode.GetName()} {msg}: {JsonConvert.SerializeObject(response)}");
}
}
}