Sets up long-running market test.
This commit is contained in:
parent
c91d9cc7dc
commit
f437c5df9d
|
@ -1,6 +1,7 @@
|
|||
using DistTestCore;
|
||||
using DistTestCore.Codex;
|
||||
using KubernetesWorkflow;
|
||||
using Logging;
|
||||
|
||||
namespace CodexNetDeployer
|
||||
{
|
||||
|
@ -52,7 +53,7 @@ namespace CodexNetDeployer
|
|||
{
|
||||
var lifecycleConfig = new DistTestCore.Configuration
|
||||
(
|
||||
kubeConfigFile: null, //config.KubeConfigFile,
|
||||
kubeConfigFile: config.KubeConfigFile,
|
||||
logPath: "null",
|
||||
logDebug: false,
|
||||
dataFilesPath: "notUsed",
|
||||
|
@ -62,7 +63,7 @@ namespace CodexNetDeployer
|
|||
|
||||
var kubeConfig = new KubernetesWorkflow.Configuration(
|
||||
k8sNamespacePrefix: config.KubeNamespace,
|
||||
kubeConfigFile: null, //config.KubeConfigFile,
|
||||
kubeConfigFile: config.KubeConfigFile,
|
||||
operationTimeout: timeset.K8sOperationTimeout(),
|
||||
retryDelay: timeset.WaitForK8sServiceDelay());
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace ContinuousTests
|
|||
[Uniform("keep", "k", "KEEP", false, "Set to '1' to retain logs of successful tests.")]
|
||||
public bool KeepPassedTestLogs { get; set; } = false;
|
||||
|
||||
[Uniform("kube-config", "kc", "KUBECONFIG", true, "Path to Kubeconfig file.")]
|
||||
public string KubeConfigFile { get; set; } = string.Empty;
|
||||
|
||||
public CodexDeployment CodexDeployment { get; set; } = null!;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,21 +15,24 @@ namespace ContinuousTests
|
|||
protected const int MinuteOne = 60;
|
||||
protected const int MinuteFive = MinuteOne * 5;
|
||||
protected const int HourOne = MinuteOne * 60;
|
||||
protected const int HourThree = HourOne * 3;
|
||||
protected const int DayOne = HourOne * 24;
|
||||
protected const int DayThree = DayOne * 3;
|
||||
|
||||
private const string UploadFailedMessage = "Unable to store block";
|
||||
|
||||
public void Initialize(CodexNode[] nodes, BaseLog log, FileManager fileManager)
|
||||
public void Initialize(CodexNode[] nodes, BaseLog log, FileManager fileManager, Configuration configuration)
|
||||
{
|
||||
Nodes = nodes;
|
||||
Log = log;
|
||||
FileManager = fileManager;
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public CodexNode[] Nodes { get; private set; } = null!;
|
||||
public BaseLog Log { get; private set; } = null!;
|
||||
public IFileManager FileManager { get; private set; } = null!;
|
||||
public Configuration Configuration { get; private set; } = null!;
|
||||
public virtual ITimeSet TimeSet { get { return new DefaultTimeSet(); } }
|
||||
|
||||
public abstract int RequiredNumberOfNodes { get; }
|
||||
|
|
|
@ -111,12 +111,12 @@ namespace ContinuousTests
|
|||
private void InitializeTest(string name)
|
||||
{
|
||||
Log($" > Running TestMoment '{name}'");
|
||||
handle.Test.Initialize(nodes, fixtureLog, fileManager);
|
||||
handle.Test.Initialize(nodes, fixtureLog, fileManager, config);
|
||||
}
|
||||
|
||||
private void DecommissionTest()
|
||||
{
|
||||
handle.Test.Initialize(null!, null!, null!);
|
||||
handle.Test.Initialize(null!, null!, null!, null!);
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
|
|
|
@ -1,25 +1,130 @@
|
|||
using DistTestCore.Codex;
|
||||
using DistTestCore;
|
||||
using DistTestCore.Codex;
|
||||
using DistTestCore.Marketplace;
|
||||
using KubernetesWorkflow;
|
||||
using Logging;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ContinuousTests.Tests
|
||||
{
|
||||
//public class MarketplaceTest : ContinuousTest
|
||||
//{
|
||||
// public override int RequiredNumberOfNodes => 1;
|
||||
// public override TimeSpan RunTestEvery => TimeSpan.FromDays(1);
|
||||
// public override TestFailMode TestFailMode => TestFailMode.AlwaysRunAllMoments;
|
||||
public class MarketplaceTest : ContinuousTest
|
||||
{
|
||||
public override int RequiredNumberOfNodes => 1;
|
||||
public override TimeSpan RunTestEvery => TimeSpan.FromDays(4);
|
||||
public override TestFailMode TestFailMode => TestFailMode.AlwaysRunAllMoments;
|
||||
|
||||
// [TestMoment(t: Zero)]
|
||||
// public void NodePostsStorageRequest()
|
||||
// {
|
||||
// //var c = new KubernetesWorkflow.WorkflowCreator(Log, new KubernetesWorkflow.Configuration());
|
||||
// //var flow = c.CreateWorkflow();
|
||||
// //var rc = flow.Start(10, KubernetesWorkflow.Location.Unspecified, new CodexContainerRecipe(), new KubernetesWorkflow.StartupConfig());
|
||||
// }
|
||||
public const int EthereumAccountIndex = 200; // TODO: Check against all other account indices of all other tests.
|
||||
|
||||
// [TestMoment(t: DayThree)]
|
||||
// public void NodeDownloadsStorageRequestData()
|
||||
// {
|
||||
private const string MarketplaceTestNamespace = "codex-continuous-marketplace";
|
||||
|
||||
// }
|
||||
//}
|
||||
private readonly ByteSize fileSize = 100.MB();
|
||||
private readonly TestToken pricePerBytePerSecond = 1.TestTokens();
|
||||
|
||||
private TestFile file = null!;
|
||||
private ContentId? cid;
|
||||
private TestToken startingBalance = null!;
|
||||
private string purchaseId = string.Empty;
|
||||
|
||||
[TestMoment(t: Zero)]
|
||||
public void NodePostsStorageRequest()
|
||||
{
|
||||
var contractDuration = TimeSpan.FromDays(3) + TimeSpan.FromHours(1);
|
||||
decimal totalDurationSeconds = Convert.ToDecimal(contractDuration.TotalSeconds);
|
||||
var expectedTotalCost = pricePerBytePerSecond.Amount * totalDurationSeconds;
|
||||
|
||||
file = FileManager.GenerateTestFile(fileSize);
|
||||
|
||||
var (workflowCreator, lifecycle) = CreateFacilities();
|
||||
var flow = workflowCreator.CreateWorkflow();
|
||||
var startupConfig = new StartupConfig();
|
||||
var codexStartConfig = new CodexStartupConfig(CodexLogLevel.Debug);
|
||||
codexStartConfig.MarketplaceConfig = new MarketplaceInitialConfig(0.Eth(), 0.TestTokens(), false);
|
||||
codexStartConfig.MarketplaceConfig.AccountIndexOverride = EthereumAccountIndex;
|
||||
startupConfig.Add(codexStartConfig);
|
||||
startupConfig.Add(Configuration.CodexDeployment.GethStartResult);
|
||||
var rc = flow.Start(1, Location.Unspecified, new CodexContainerRecipe(), startupConfig);
|
||||
|
||||
try
|
||||
{
|
||||
var account = Configuration.CodexDeployment.GethStartResult.MarketplaceNetwork.Bootstrap.AllAccounts.Accounts[EthereumAccountIndex];
|
||||
var tokenAddress = Configuration.CodexDeployment.GethStartResult.MarketplaceNetwork.Marketplace.TokenAddress;
|
||||
|
||||
var interaction = Configuration.CodexDeployment.GethStartResult.MarketplaceNetwork.Bootstrap.StartInteraction(lifecycle);
|
||||
interaction.MintTestTokens(new[] { account.Account }, expectedTotalCost, tokenAddress);
|
||||
|
||||
var container = rc.Containers[0];
|
||||
var marketplaceNetwork = Configuration.CodexDeployment.GethStartResult.MarketplaceNetwork;
|
||||
var codexAccess = new CodexAccess(lifecycle, container);
|
||||
var marketAccess = new MarketplaceAccess(lifecycle, marketplaceNetwork, account, codexAccess);
|
||||
|
||||
cid = UploadFile(codexAccess.Node, file);
|
||||
Assert.That(cid, Is.Not.Null);
|
||||
|
||||
startingBalance = marketAccess.GetBalance();
|
||||
|
||||
purchaseId = marketAccess.RequestStorage(
|
||||
contentId: cid!,
|
||||
pricePerBytePerSecond: pricePerBytePerSecond,
|
||||
requiredCollateral: 100.TestTokens(),
|
||||
minRequiredNumberOfNodes: 3,
|
||||
proofProbability: 10,
|
||||
duration: contractDuration);
|
||||
|
||||
Assert.That(!string.IsNullOrEmpty(purchaseId));
|
||||
}
|
||||
finally
|
||||
{
|
||||
flow.Stop(rc);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMoment(t: DayThree)]
|
||||
public void StoredDataIsAvailableAfterThreeDays()
|
||||
{
|
||||
var (workflowCreator, lifecycle) = CreateFacilities();
|
||||
var flow = workflowCreator.CreateWorkflow();
|
||||
var startupConfig = new StartupConfig();
|
||||
var codexStartConfig = new CodexStartupConfig(CodexLogLevel.Debug);
|
||||
startupConfig.Add(codexStartConfig);
|
||||
var rc = flow.Start(1, Location.Unspecified, new CodexContainerRecipe(), startupConfig);
|
||||
|
||||
try
|
||||
{
|
||||
var container = rc.Containers[0];
|
||||
var codexAccess = new CodexAccess(lifecycle, container);
|
||||
|
||||
var result = DownloadContent(codexAccess.Node, cid!);
|
||||
|
||||
file.AssertIsEqual(result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
flow.Stop(rc);
|
||||
}
|
||||
}
|
||||
|
||||
private (WorkflowCreator, TestLifecycle) CreateFacilities()
|
||||
{
|
||||
var lifecycleConfig = new DistTestCore.Configuration
|
||||
(
|
||||
kubeConfigFile: Configuration.KubeConfigFile,
|
||||
logPath: "null",
|
||||
logDebug: false,
|
||||
dataFilesPath: "notUsed",
|
||||
codexLogLevel: CodexLogLevel.Debug,
|
||||
runnerLocation: TestRunnerLocation.InternalToCluster
|
||||
);
|
||||
|
||||
var kubeConfig = new KubernetesWorkflow.Configuration(
|
||||
k8sNamespacePrefix: MarketplaceTestNamespace,
|
||||
kubeConfigFile: Configuration.KubeConfigFile,
|
||||
operationTimeout: TimeSet.K8sOperationTimeout(),
|
||||
retryDelay: TimeSet.WaitForK8sServiceDelay());
|
||||
|
||||
var workflowCreator = new WorkflowCreator(Log, kubeConfig, testNamespacePostfix: string.Empty);
|
||||
var lifecycle = new TestLifecycle(new NullLog(), lifecycleConfig, TimeSet, workflowCreator);
|
||||
|
||||
return (workflowCreator, lifecycle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using Logging;
|
||||
|
||||
namespace CodexNetDeployer
|
||||
namespace Logging
|
||||
{
|
||||
public class NullLog : TestLog
|
||||
{
|
||||
|
@ -15,12 +13,10 @@ namespace CodexNetDeployer
|
|||
|
||||
public override void Log(string message)
|
||||
{
|
||||
//Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public override void Debug(string message = "", int skipFrames = 0)
|
||||
{
|
||||
//Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public override void Error(string message)
|
Loading…
Reference in New Issue